Move to kotlin and streamline more base stuff
This commit is contained in:
parent
58598f7e3f
commit
f23be0c213
@ -35,13 +35,13 @@ public class BlockAndroidStation extends BlockMattery implements EntityBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResult use(BlockState p_60503_, Level level, BlockPos pos, Player ply, InteractionHand p_60507_, BlockHitResult p_60508_) {
|
public InteractionResult use(BlockState blockState, Level level, BlockPos blockPos, Player ply, InteractionHand hand, BlockHitResult blockHitResult) {
|
||||||
LazyOptional<IAndroidCapability> cap = ply.getCapability(MatteryCapability.ANDROID);
|
LazyOptional<IAndroidCapability> cap = ply.getCapability(MatteryCapability.ANDROID);
|
||||||
|
|
||||||
if (cap.resolve().isEmpty() || !cap.resolve().get().isAndroid())
|
if (cap.resolve().isEmpty() || !cap.resolve().get().isAndroid())
|
||||||
return InteractionResult.FAIL;
|
return InteractionResult.FAIL;
|
||||||
|
|
||||||
return super.use(p_60503_, level, pos, ply, p_60507_, p_60508_);
|
return super.use(blockState, level, blockPos, ply, hand, blockHitResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.block;
|
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
|
||||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public abstract class BlockMatteryRotatable extends BlockMattery {
|
|
||||||
public static final EnumProperty<Direction> FACING = EnumProperty.create(
|
|
||||||
"facing",
|
|
||||||
Direction.class,
|
|
||||||
Direction.SOUTH,
|
|
||||||
Direction.WEST,
|
|
||||||
Direction.NORTH,
|
|
||||||
Direction.EAST);
|
|
||||||
|
|
||||||
public BlockMatteryRotatable() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
registerDefaultState(this.getStateDefinition().any().setValue(FACING, Direction.SOUTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
|
||||||
builder.add(FACING);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
|
||||||
return this.defaultBlockState().setValue(FACING, faceToPlayer(context) ? context.getHorizontalDirection().getOpposite() : context.getHorizontalDirection());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean faceToPlayer(BlockPlaceContext context) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
|
||||||
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class ContainerIteratorCapability<T> implements java.util.Iterator<T>, Iterable<T> {
|
|
||||||
private final Container container;
|
|
||||||
private final Capability<T> cap;
|
|
||||||
private int index = 0;
|
|
||||||
private T next_stack;
|
|
||||||
|
|
||||||
public ContainerIteratorCapability(Container container, Capability<T> cap) {
|
|
||||||
this.container = container;
|
|
||||||
this.cap = cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
if (index >= container.getContainerSize() && next_stack == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (next_stack == null) {
|
|
||||||
while (next_stack == null && index < container.getContainerSize()) {
|
|
||||||
ItemStack get = container.getItem(index);
|
|
||||||
|
|
||||||
if (!get.isEmpty()) {
|
|
||||||
get.getCapability(cap).ifPresent(t -> next_stack = t);
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next_stack != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T next() {
|
|
||||||
T _next_stack = next_stack;
|
|
||||||
next_stack = null;
|
|
||||||
return _next_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<T> iterator() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void consume(Consumer<T> consumer) {
|
|
||||||
for (T t : this) {
|
|
||||||
consumer.accept(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
|
||||||
|
|
||||||
import net.minecraft.world.Container;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class ContainerIteratorItemStack implements java.util.Iterator<ItemStack>, Iterable<ItemStack> {
|
|
||||||
private final Container container;
|
|
||||||
private int index = 0;
|
|
||||||
private ItemStack next_stack;
|
|
||||||
|
|
||||||
public ContainerIteratorItemStack(Container container) {
|
|
||||||
this.container = container;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
if (index >= container.getContainerSize() && next_stack == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (next_stack == null) {
|
|
||||||
while (next_stack == null && index < container.getContainerSize()) {
|
|
||||||
ItemStack get = container.getItem(index);
|
|
||||||
|
|
||||||
if (!get.isEmpty()) {
|
|
||||||
next_stack = get;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next_stack != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack next() {
|
|
||||||
ItemStack _next_stack = next_stack;
|
|
||||||
next_stack = null;
|
|
||||||
return _next_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<ItemStack> iterator() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void consume(Consumer<ItemStack> consumer) {
|
|
||||||
for (ItemStack t : this) {
|
|
||||||
consumer.accept(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
|
||||||
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface MatteryContainerExtractValidator {
|
|
||||||
boolean apply(int slot, int amount, @Nonnull ItemStack stack);
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
|
||||||
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface MatteryContainerInsertValidator {
|
|
||||||
boolean apply(int slot, @Nonnull ItemStack stack);
|
|
||||||
}
|
|
@ -51,7 +51,7 @@ inline fun CompoundTag.ifHas(s: String, type: Byte, consumer: (Tag) -> Unit) {
|
|||||||
inline fun <reified T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
inline fun <reified T : Tag> CompoundTag.ifHas(s: String, type: Class<T>, consumer: (T) -> Unit) {
|
||||||
val tag = get(s)
|
val tag = get(s)
|
||||||
|
|
||||||
if (tag != null && tag::class.java == type) {
|
if (tag != null && tag::class.java === type) {
|
||||||
consumer(tag as T)
|
consumer(tag as T)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.block
|
package ru.dbotthepony.mc.otm.block
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.world.item.context.BlockPlaceContext
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.EntityBlock
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
@ -36,6 +37,10 @@ class BlockDriveViewer : BlockMatteryRotatable(), EntityBlock {
|
|||||||
builder.add(DRIVE_PRESENT)
|
builder.add(DRIVE_PRESENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getStateForPlacement(context: BlockPlaceContext): BlockState {
|
||||||
|
return super.getStateForPlacement(context)!!.setValue(DRIVE_PRESENT, false)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DRIVE_PRESENT = BooleanProperty.create("drive")
|
val DRIVE_PRESENT = BooleanProperty.create("drive")
|
||||||
}
|
}
|
||||||
|
@ -1,67 +1,121 @@
|
|||||||
package ru.dbotthepony.mc.otm.block;
|
package ru.dbotthepony.mc.otm.block
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult
|
||||||
import net.minecraft.world.MenuProvider;
|
import net.minecraft.world.MenuProvider
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.item.context.BlockPlaceContext
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.EntityBlock
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.material.Material;
|
import net.minecraft.world.level.block.state.StateDefinition
|
||||||
import net.minecraft.world.level.material.MaterialColor;
|
import net.minecraft.world.level.block.state.properties.EnumProperty
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.level.material.Material
|
||||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMattery;
|
import net.minecraft.world.level.material.MaterialColor
|
||||||
|
import net.minecraft.world.phys.BlockHitResult
|
||||||
|
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMattery
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
abstract class BlockMattery @JvmOverloads constructor(
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
properties: Properties = DEFAULT_PROPERTIES
|
||||||
|
) : Block(properties) {
|
||||||
|
override fun setPlacedBy(
|
||||||
|
level: Level,
|
||||||
|
blockPos: BlockPos,
|
||||||
|
blockState: BlockState,
|
||||||
|
entity: LivingEntity?,
|
||||||
|
itemStack: ItemStack
|
||||||
|
) {
|
||||||
|
if (this is EntityBlock && itemStack.hasCustomHoverName() && !level.isClientSide) {
|
||||||
|
val tile = level.getBlockEntity(blockPos)
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
if (tile is BlockEntityMattery)
|
||||||
@ParametersAreNonnullByDefault
|
tile.customDisplayName = itemStack.displayName
|
||||||
public abstract class BlockMattery extends Block {
|
|
||||||
public BlockMattery(Properties p_49795_) {
|
|
||||||
super(p_49795_);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockMattery() {
|
|
||||||
this(BlockBehaviour.Properties.of(Material.STONE, MaterialColor.METAL).requiresCorrectToolForDrops().strength(1.5F, 25.0F));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlacedBy(Level p_49847_, BlockPos p_49848_, BlockState p_49849_, @Nullable LivingEntity p_49850_, ItemStack p_49851_) {
|
|
||||||
if (this instanceof EntityBlock && p_49851_.hasCustomHoverName() && !p_49847_.isClientSide && p_49847_.getBlockEntity(p_49848_) instanceof BlockEntityMattery tile) {
|
|
||||||
tile.setDisplayName(p_49851_.getDisplayName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setPlacedBy(p_49847_, p_49848_, p_49849_, p_49850_, p_49851_);
|
super.setPlacedBy(level, blockPos, blockState, entity, itemStack)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun use(
|
||||||
@SuppressWarnings("deprecation")
|
blockState: BlockState,
|
||||||
public InteractionResult use(BlockState p_60503_, Level level, BlockPos pos, Player ply, InteractionHand p_60507_, BlockHitResult p_60508_) {
|
level: Level,
|
||||||
if (this instanceof EntityBlock && !level.isClientSide && level.getBlockEntity(pos) instanceof MenuProvider tile) {
|
blockPos: BlockPos,
|
||||||
ply.openMenu(tile);
|
ply: Player,
|
||||||
return InteractionResult.CONSUME;
|
hand: InteractionHand,
|
||||||
|
blockHitResult: BlockHitResult
|
||||||
|
): InteractionResult {
|
||||||
|
if (this is EntityBlock && !level.isClientSide) {
|
||||||
|
val tile = level.getBlockEntity(blockPos)
|
||||||
|
|
||||||
|
if (tile is MenuProvider) {
|
||||||
|
ply.openMenu(tile)
|
||||||
|
return InteractionResult.CONSUME
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this instanceof EntityBlock && level.isClientSide)
|
if (this is EntityBlock && level.isClientSide)
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS
|
||||||
|
|
||||||
return super.use(p_60503_, level, pos, ply, p_60507_, p_60508_);
|
return super.use(blockState, level, blockPos, ply, hand, blockHitResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun neighborChanged(
|
||||||
@SuppressWarnings("deprecation")
|
state: BlockState,
|
||||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block sender, BlockPos sender_pos, boolean flag) {
|
level: Level,
|
||||||
super.neighborChanged(state, level, pos, sender, sender_pos, flag);
|
pos: BlockPos,
|
||||||
|
sender: Block,
|
||||||
|
sender_pos: BlockPos,
|
||||||
|
flag: Boolean
|
||||||
|
) {
|
||||||
|
super.neighborChanged(state, level, pos, sender, sender_pos, flag)
|
||||||
|
|
||||||
if (this instanceof EntityBlock && !level.isClientSide && level.getBlockEntity(pos) instanceof BlockEntityMattery tile) {
|
if (this is EntityBlock && !level.isClientSide) {
|
||||||
tile.setRedstoneSignal(level.getBestNeighborSignal(pos));
|
val tile = level.getBlockEntity(pos)
|
||||||
|
|
||||||
|
if (tile is BlockEntityMattery)
|
||||||
|
tile.redstoneSignal = level.getBestNeighborSignal(pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val DEFAULT_PROPERTIES: Properties = Properties.of(Material.STONE, MaterialColor.METAL).requiresCorrectToolForDrops().strength(1.5f, 25.0f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BlockMatteryRotatable @JvmOverloads constructor(properties: Properties = DEFAULT_PROPERTIES) : BlockMattery(properties) {
|
||||||
|
init {
|
||||||
|
registerDefaultState(getStateDefinition().any().setValue(FACING, Direction.SOUTH))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
|
||||||
|
builder.add(FACING)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {
|
||||||
|
return defaultBlockState().setValue(
|
||||||
|
FACING,
|
||||||
|
if (faceToPlayer(context)) context.horizontalDirection.opposite else context.horizontalDirection
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun faceToPlayer(context: BlockPlaceContext): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val FACING = EnumProperty.create(
|
||||||
|
"facing",
|
||||||
|
Direction::class.java,
|
||||||
|
Direction.SOUTH,
|
||||||
|
Direction.WEST,
|
||||||
|
Direction.NORTH,
|
||||||
|
Direction.EAST
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import net.minecraftforge.common.util.LazyOptional
|
|||||||
import net.minecraftforge.energy.CapabilityEnergy
|
import net.minecraftforge.energy.CapabilityEnergy
|
||||||
import net.minecraftforge.energy.IEnergyStorage
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import net.minecraftforge.items.IItemHandler
|
|
||||||
import ru.dbotthepony.mc.otm.Registry
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.block.BlockBatteryBank
|
import ru.dbotthepony.mc.otm.block.BlockBatteryBank
|
||||||
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||||
@ -40,8 +39,8 @@ import javax.annotation.ParametersAreNonnullByDefault
|
|||||||
class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.BATTERY_BANK, p_155229_, p_155230_) {
|
class BlockEntityBatteryBank(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.BATTERY_BANK, p_155229_, p_155230_) {
|
||||||
// 6 на 2
|
// 6 на 2
|
||||||
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 6 * 2) {
|
val container: MatteryContainer = object : MatteryContainer(this::setChanged, 6 * 2) {
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
|
|
||||||
val level = level
|
val level = level
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
|
@ -31,14 +31,14 @@ class BlockEntityDriveRack(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val drives: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
|
val drives: MatteryContainer = object : MatteryContainer(this::setChanged, 4) {
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
|
|
||||||
old_state.getCapability(MatteryCapability.DRIVE).ifPresent {
|
old.getCapability(MatteryCapability.DRIVE).ifPresent {
|
||||||
cell.computeIfAbsent(it.storageIdentity()) {c -> PoweredVirtualComponent(c, energy)}.remove(it)
|
cell.computeIfAbsent(it.storageIdentity()) {c -> PoweredVirtualComponent(c, energy)}.remove(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
new_state.getCapability(MatteryCapability.DRIVE).ifPresent {
|
new.getCapability(MatteryCapability.DRIVE).ifPresent {
|
||||||
cell.computeIfAbsent(it.storageIdentity()) {c -> PoweredVirtualComponent(c, energy)}.add(it)
|
cell.computeIfAbsent(it.storageIdentity()) {c -> PoweredVirtualComponent(c, energy)}.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import net.minecraft.world.entity.player.Inventory
|
|||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.world.level.Level
|
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
@ -54,8 +53,8 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val drive_slot: MatteryContainer = object : MatteryContainer(this::setChanged, 1) {
|
val drive_slot: MatteryContainer = object : MatteryContainer(this::setChanged, 1) {
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
|
|
||||||
val level = level
|
val level = level
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
@ -63,7 +62,7 @@ class BlockEntityDriveViewer(p_155229_: BlockPos, p_155230_: BlockState) : Block
|
|||||||
if (!isRemoved) {
|
if (!isRemoved) {
|
||||||
var state = blockState
|
var state = blockState
|
||||||
|
|
||||||
if (new_state.getCapability(MatteryCapability.DRIVE).isPresent) {
|
if (new.getCapability(MatteryCapability.DRIVE).isPresent) {
|
||||||
state = state.setValue(BlockDriveViewer.DRIVE_PRESENT, true)
|
state = state.setValue(BlockDriveViewer.DRIVE_PRESENT, true)
|
||||||
} else {
|
} else {
|
||||||
state = state.setValue(BlockDriveViewer.DRIVE_PRESENT, false)
|
state = state.setValue(BlockDriveViewer.DRIVE_PRESENT, false)
|
||||||
|
@ -2,35 +2,36 @@ package ru.dbotthepony.mc.otm.block.entity
|
|||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.nbt.CompoundTag
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
import net.minecraft.server.level.ServerLevel
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
|
||||||
import net.minecraftforge.items.CapabilityItemHandler
|
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.nbt.CompoundTag
|
|
||||||
import net.minecraft.network.chat.Component
|
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
|
||||||
import net.minecraft.network.chat.TranslatableComponent
|
|
||||||
import net.minecraft.server.level.ServerLevel
|
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraft.world.level.block.Block
|
import net.minecraft.world.level.block.Block
|
||||||
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraftforge.common.capabilities.Capability
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler
|
||||||
import ru.dbotthepony.mc.otm.Registry
|
import ru.dbotthepony.mc.otm.Registry
|
||||||
import ru.dbotthepony.mc.otm.block.BlockMatterBottler
|
import ru.dbotthepony.mc.otm.block.BlockMatterBottler
|
||||||
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler.MatterDirection
|
||||||
|
import ru.dbotthepony.mc.otm.capability.matter.MatterHandlerCapability
|
||||||
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
|
import ru.dbotthepony.mc.otm.container.MatteryContainerHandler
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||||
import ru.dbotthepony.mc.otm.ifHas
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
|
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
|
||||||
import ru.dbotthepony.mc.otm.set
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
|
class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||||
@ -86,8 +87,8 @@ class BlockEntityMatterBottler(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
updateBlockState()
|
updateBlockState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,8 @@ class BlockEntityMatterCapacitorBank(p_155229_: BlockPos, p_155230_: BlockState)
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val matterContainer = object : MatteryContainer(this::setChangedLight, 6 * 2) {
|
val matterContainer = object : MatteryContainer(this::setChangedLight, 6 * 2) {
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
val level = level
|
val level = level
|
||||||
|
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
|
@ -75,7 +75,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
|
|||||||
{ slot: Int, amount: Int, stack: ItemStack? -> slot == 1 })
|
{ slot: Int, amount: Int, stack: ItemStack? -> slot == 1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDefaultDisplayName(): Component? {
|
override fun getDefaultDisplayName(): Component {
|
||||||
return MACHINE_NAME
|
return MACHINE_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,182 +1,169 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
import net.minecraft.nbt.ByteTag;
|
import net.minecraft.world.MenuProvider
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import java.lang.Runnable
|
||||||
import net.minecraft.nbt.StringTag;
|
import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.server.level.ServerLevel
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.client.multiplayer.ClientLevel
|
||||||
import net.minecraft.world.MenuProvider;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.core.SectionPos
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||||
import net.minecraft.world.level.Level;
|
import java.lang.ref.WeakReference
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.entity.player.Player
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
import net.minecraft.nbt.StringTag
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraft.nbt.ByteTag
|
||||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
import net.minecraft.network.chat.Component
|
||||||
|
import net.minecraft.world.level.Level
|
||||||
|
import net.minecraft.world.level.chunk.ChunkStatus
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
abstract class BlockEntityMattery(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
var customDisplayName: Component? = null
|
||||||
import java.lang.ref.WeakReference;
|
var redstoneSignal = 0
|
||||||
import java.util.function.Consumer;
|
set(level) {
|
||||||
|
val old = isBlockedByRedstone
|
||||||
|
field = level
|
||||||
|
val state = isBlockedByRedstone
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
if (old != state) {
|
||||||
@ParametersAreNonnullByDefault
|
redstoneStatusUpdated(state, old)
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public abstract class BlockEntityMattery extends BlockEntity implements MenuProvider {
|
|
||||||
protected Component display_name;
|
|
||||||
protected RedstoneSetting redstone_setting = RedstoneSetting.LOW;
|
|
||||||
protected int redstone_signal = 0;
|
|
||||||
|
|
||||||
public BlockEntityMattery(BlockEntityType<?> p_155228_, BlockPos p_155229_, BlockState p_155230_) {
|
|
||||||
super(p_155228_, p_155229_, p_155230_);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDisplayName(Component text) {
|
|
||||||
display_name = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected Component getDefaultDisplayName();
|
|
||||||
|
|
||||||
protected void tickOnce(Runnable func) {
|
|
||||||
if (level != null)
|
|
||||||
OverdriveThatMatters.tickOnce(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tickOnceServer(Runnable func) {
|
|
||||||
if (level instanceof ServerLevel level)
|
|
||||||
OverdriveThatMatters.tickOnce(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tickOnceClient(Runnable func) {
|
|
||||||
if (level instanceof ClientLevel level)
|
|
||||||
OverdriveThatMatters.tickOnce(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tickOnce(Consumer<Level> func) {
|
|
||||||
if (level != null)
|
|
||||||
OverdriveThatMatters.tickOnceSelf(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tickOnceServer(Consumer<Level> func) {
|
|
||||||
if (level instanceof ServerLevel level)
|
|
||||||
OverdriveThatMatters.tickOnceSelf(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void tickOnceClient(Consumer<Level> func) {
|
|
||||||
if (level instanceof ClientLevel level)
|
|
||||||
OverdriveThatMatters.tickOnceSelf(level, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> LazyOptional<T> getAndBind(LazyOptional<T> old, @Nullable ICapabilityProvider provider, Capability<T> cap, @Nullable Direction side, Runnable invalidate) {
|
|
||||||
final var get = provider != null ? provider.getCapability(cap, side) : LazyOptional.empty();
|
|
||||||
|
|
||||||
if (old != get) {
|
|
||||||
if (get.isPresent()) {
|
|
||||||
final var ref = new WeakReference<>(invalidate);
|
|
||||||
|
|
||||||
get.addListener((l) -> {
|
|
||||||
final var self = ref.get();
|
|
||||||
|
|
||||||
if (self != null) {
|
|
||||||
self.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return get.cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
return get.cast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Component getDisplayName() {
|
|
||||||
return display_name != null ? display_name : getDefaultDisplayName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
abstract public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply);
|
|
||||||
|
|
||||||
protected void redstoneStatusUpdated(boolean new_blocked, boolean old_blocked) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedstoneSignal(int level) {
|
|
||||||
final var old = isBlockedByRedstone();
|
|
||||||
redstone_signal = level;
|
|
||||||
final var state = isBlockedByRedstone();
|
|
||||||
|
|
||||||
if (old != state) {
|
|
||||||
redstoneStatusUpdated(state, old);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedstoneSetting(RedstoneSetting setting) {
|
|
||||||
final var old = isBlockedByRedstone();
|
|
||||||
redstone_setting = setting;
|
|
||||||
final var state = isBlockedByRedstone();
|
|
||||||
|
|
||||||
if (old != state) {
|
|
||||||
redstoneStatusUpdated(state, old);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RedstoneSetting getRedstoneSetting() {
|
|
||||||
return redstone_setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isBlockedByRedstone() {
|
|
||||||
switch (redstone_setting) {
|
|
||||||
case LOW -> {
|
|
||||||
return redstone_signal > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case HIGH -> {
|
|
||||||
return redstone_signal <= 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
var redstoneSetting: RedstoneSetting = RedstoneSetting.LOW
|
||||||
|
set(setting) {
|
||||||
|
val old = isBlockedByRedstone
|
||||||
|
field = setting
|
||||||
|
val state = isBlockedByRedstone
|
||||||
|
if (old != state) {
|
||||||
|
redstoneStatusUpdated(state, old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val isBlockedByRedstone: Boolean
|
||||||
|
get() {
|
||||||
|
when (redstoneSetting) {
|
||||||
|
RedstoneSetting.LOW -> {
|
||||||
|
return redstoneSignal > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
RedstoneSetting.HIGH -> {
|
||||||
|
return redstoneSignal <= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
RedstoneSetting.IGNORED -> {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun getDefaultDisplayName(): Component
|
||||||
|
abstract override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu?
|
||||||
|
|
||||||
|
protected fun tickOnce(func: Runnable) {
|
||||||
|
val level = level
|
||||||
|
if (level != null) OverdriveThatMatters.tickOnce(level, func)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected fun tickOnceServer(func: Runnable) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
val level = level
|
||||||
super.saveAdditional(nbt);
|
if (level is ServerLevel) OverdriveThatMatters.tickOnce(level, func)
|
||||||
|
|
||||||
if (display_name != null)
|
|
||||||
nbt.putString("Name", Component.Serializer.toJson(display_name));
|
|
||||||
|
|
||||||
nbt.putByte("redstone", (byte) redstone_setting.ordinal());
|
|
||||||
nbt.putByte("redstone_signal", (byte) redstone_signal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(CompoundTag nbt) {
|
protected fun tickOnceClient(func: Runnable) {
|
||||||
super.load(nbt);
|
val level = level
|
||||||
|
if (level is ClientLevel) OverdriveThatMatters.tickOnce(level, func)
|
||||||
|
}
|
||||||
|
|
||||||
if (nbt.get("Name") instanceof StringTag tag)
|
protected fun tickOnce(func: Consumer<Level>) {
|
||||||
display_name = Component.Serializer.fromJson(tag.getAsString());
|
val level = level
|
||||||
|
if (level != null) OverdriveThatMatters.tickOnceSelf(level, func)
|
||||||
|
}
|
||||||
|
|
||||||
if (nbt.get("redstone") instanceof ByteTag tag)
|
protected fun tickOnceServer(func: Consumer<Level>) {
|
||||||
redstone_setting = RedstoneSetting.get(tag.getAsByte());
|
val level = level
|
||||||
|
if (level is ServerLevel) OverdriveThatMatters.tickOnceSelf(level, func)
|
||||||
|
}
|
||||||
|
|
||||||
if (nbt.get("redstone_signal") instanceof ByteTag tag)
|
protected fun tickOnceClient(func: Consumer<Level>) {
|
||||||
redstone_signal = tag.getAsByte();
|
val level = level
|
||||||
|
if (level is ClientLevel) OverdriveThatMatters.tickOnceSelf(level, func)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun <T> getAndBind(
|
||||||
|
old: LazyOptional<T>,
|
||||||
|
provider: ICapabilityProvider?,
|
||||||
|
cap: Capability<T>,
|
||||||
|
side: Direction,
|
||||||
|
invalidate: Runnable
|
||||||
|
): LazyOptional<T> {
|
||||||
|
val get = provider?.getCapability(cap, side) ?: LazyOptional.empty()
|
||||||
|
|
||||||
|
if (old !== get) {
|
||||||
|
if (get.isPresent) {
|
||||||
|
val ref = WeakReference(invalidate)
|
||||||
|
get.addListener {
|
||||||
|
ref.get()?.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return get.cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
return get.cast()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDisplayName(): Component {
|
||||||
|
return customDisplayName ?: getDefaultDisplayName()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) {}
|
||||||
|
|
||||||
|
override fun saveAdditional(nbt: CompoundTag) {
|
||||||
|
super.saveAdditional(nbt)
|
||||||
|
|
||||||
|
val customDisplayName = customDisplayName
|
||||||
|
if (customDisplayName != null)
|
||||||
|
nbt.putString("Name", Component.Serializer.toJson(customDisplayName))
|
||||||
|
|
||||||
|
nbt["redstone"] = redstoneSetting.ordinal.toByte()
|
||||||
|
nbt["redstone_signal"] = redstoneSignal.toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(nbt: CompoundTag) {
|
||||||
|
super.load(nbt)
|
||||||
|
|
||||||
|
nbt.ifHas("Name", StringTag::class.java) {
|
||||||
|
customDisplayName = Component.Serializer.fromJson(it.asString)
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.ifHas("redstone", ByteTag::class.java) {
|
||||||
|
redstoneSetting = RedstoneSetting.get(it.asInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.ifHas("redstone_signal", ByteTag::class.java) {
|
||||||
|
redstoneSignal = it.asInt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just to mark chunk unsaved
|
// Just to mark chunk unsaved
|
||||||
public void setChangedLight() {
|
open fun setChangedLight() {
|
||||||
if (level != null) {
|
val level = level
|
||||||
if (level.hasChunkAt(getBlockPos()))
|
if (level is ServerLevel) {
|
||||||
level.getChunkAt(getBlockPos()).setUnsaved(true);
|
level.chunkSource.getChunkNow(
|
||||||
|
SectionPos.blockToSectionCoord(blockPos.x),
|
||||||
|
SectionPos.blockToSectionCoord(blockPos.z))?.isUnsaved = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,132 +1,80 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.energy.CapabilityEnergy
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import net.minecraftforge.energy.CapabilityEnergy;
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import net.minecraftforge.energy.IEnergyStorage;
|
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
|
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
|
import ru.dbotthepony.mc.otm.core.Fraction
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer;
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
import ru.dbotthepony.mc.otm.core.Fraction;
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
abstract class BlockEntityMatteryPowered(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(p_155228_, p_155229_, p_155230_) {
|
||||||
import javax.annotation.Nullable;
|
protected lateinit var energy: MatteryMachineEnergyStorage
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
private var resolverEnergy = LazyOptional.of { energy }
|
||||||
import java.math.BigDecimal;
|
private var valid = true
|
||||||
import java.util.Optional;
|
val batteryContainer = MatteryContainer(this::setChangedLight, 1)
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
protected fun batteryChargeLoop() {
|
||||||
@ParametersAreNonnullByDefault
|
var demand = energy.receiveEnergyOuter(energy.missingPower, true)
|
||||||
abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
|
if (demand.isZero()) return
|
||||||
protected MatteryMachineEnergyStorage energy = null;
|
|
||||||
private LazyOptional<MatteryMachineEnergyStorage> energy_resolver = LazyOptional.of(() -> energy);
|
|
||||||
private boolean valid = true;
|
|
||||||
|
|
||||||
public MatteryContainer battery_container = new MatteryContainer(this::setChanged, 1);
|
for (stack in batteryContainer) {
|
||||||
|
if (!stack.isEmpty) {
|
||||||
protected void batteryChargeLoop() {
|
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||||
if (energy == null)
|
if (it is IMatteryEnergyStorage) {
|
||||||
return;
|
val diff = it.extractEnergyOuter(demand, false)
|
||||||
|
energy.receiveEnergyInner(diff, false)
|
||||||
if (energy.getMissingPower().compareTo(Fraction.ZERO) <= 0)
|
demand -= diff
|
||||||
return;
|
} else {
|
||||||
|
val diff = it.extractEnergy(demand, false)
|
||||||
var demand = energy.getMissingPower();
|
energy.receiveEnergyInner(diff, false)
|
||||||
|
demand -= diff
|
||||||
if (demand.compareTo(Fraction.ZERO) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
demand = demand.min(energy.receiveEnergyOuter(demand, true));
|
|
||||||
|
|
||||||
for (int i = 0; i < battery_container.getContainerSize() && demand.compareTo(Fraction.ZERO) > 0; i++) {
|
|
||||||
final var stack = battery_container.getItem(i);
|
|
||||||
|
|
||||||
if (!stack.isEmpty()) {
|
|
||||||
final var mattery_storage = stack.getCapability(MatteryCapability.ENERGY).resolve();
|
|
||||||
|
|
||||||
if (mattery_storage.isPresent()) {
|
|
||||||
final var drain = mattery_storage.get().extractEnergyOuter(demand, true);
|
|
||||||
|
|
||||||
if (drain.compareTo(Fraction.ZERO) != 0) {
|
|
||||||
final var receive = energy.receiveEnergyOuter(drain, true);
|
|
||||||
|
|
||||||
mattery_storage.get().extractEnergyOuter(receive, false);
|
|
||||||
energy.receiveEnergyOuter(receive, false);
|
|
||||||
|
|
||||||
demand = demand.minus(receive);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final var storage = stack.getCapability(CapabilityEnergy.ENERGY).resolve();
|
|
||||||
|
|
||||||
if (storage.isPresent()) {
|
|
||||||
final var drain = MatteryCapability.drainFE(storage.get(), demand, true);
|
|
||||||
|
|
||||||
if (drain.compareTo(Fraction.ZERO) != 0) {
|
|
||||||
final var receive = energy.receiveEnergyOuter(drain, true);
|
|
||||||
|
|
||||||
MatteryCapability.drainFE(storage.get(), receive, false);
|
|
||||||
energy.receiveEnergyOuter(receive, false);
|
|
||||||
|
|
||||||
demand = demand.minus(receive);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (demand <= Fraction.ZERO)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockEntityMatteryPowered(BlockEntityType<?> p_155228_, BlockPos p_155229_, BlockState p_155230_) {
|
override fun invalidateCaps() {
|
||||||
super(p_155228_, p_155229_, p_155230_);
|
super.invalidateCaps()
|
||||||
|
valid = false
|
||||||
|
resolverEnergy.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun reviveCaps() {
|
||||||
public void invalidateCaps() {
|
super.reviveCaps()
|
||||||
super.invalidateCaps();
|
valid = true
|
||||||
valid = false;
|
resolverEnergy = LazyOptional.of { energy }
|
||||||
energy_resolver.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
public void reviveCaps() {
|
if (valid && (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY))
|
||||||
super.reviveCaps();
|
return resolverEnergy.cast()
|
||||||
valid = true;
|
|
||||||
energy_resolver = LazyOptional.of(() -> energy);
|
return super.getCapability(cap, side)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
public override fun saveAdditional(nbt: CompoundTag) {
|
||||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
|
super.saveAdditional(nbt)
|
||||||
if (valid && (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) && energy != null) {
|
nbt["energy_cap"] = energy.serializeNBT()
|
||||||
return energy_resolver.cast();
|
nbt["battery_container"] = batteryContainer.serializeNBT()
|
||||||
}
|
|
||||||
|
|
||||||
return super.getCapability(cap, side);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun load(nbt: CompoundTag) {
|
||||||
public void saveAdditional(CompoundTag nbt) {
|
nbt.ifHas("energy_cap", CompoundTag::class.java, energy::deserializeNBT)
|
||||||
super.saveAdditional(nbt);
|
nbt.ifHas("battery_container", CompoundTag::class.java, batteryContainer::deserializeNBT)
|
||||||
|
super.load(nbt)
|
||||||
if (energy != null)
|
|
||||||
nbt.put("energy_cap", energy.serializeNBT());
|
|
||||||
|
|
||||||
nbt.put("battery_container", battery_container.serializeNBT());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load(CompoundTag nbt) {
|
|
||||||
if (energy != null && nbt.get("energy_cap") instanceof CompoundTag tag)
|
|
||||||
energy.deserializeNBT(tag);
|
|
||||||
|
|
||||||
if (nbt.contains("battery_container") && nbt.get("battery_container") instanceof CompoundTag tag)
|
|
||||||
battery_container = MatteryContainer.of(this::setChanged, tag, 1);
|
|
||||||
|
|
||||||
super.load(nbt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,6 @@ import net.minecraft.core.BlockPos
|
|||||||
import net.minecraft.world.level.block.state.BlockState
|
import net.minecraft.world.level.block.state.BlockState
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||||
import java.lang.Runnable
|
|
||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
import ru.dbotthepony.mc.otm.capability.matter.PatternState
|
||||||
@ -44,19 +43,19 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
private val resolverNode = LazyOptional.of { this }
|
private val resolverNode = LazyOptional.of { this }
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val patterns: MatteryContainer = object : MatteryContainer(Runnable { this.setChanged() }, 8) {
|
val patterns: MatteryContainer = object : MatteryContainer(this::setChanged, 8) {
|
||||||
override fun setChanged(slot: Int, new_state: ItemStack, old_state: ItemStack) {
|
override fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
val grid = node.graph as MatterNetworkGraph?
|
val grid = node.graph as MatterNetworkGraph?
|
||||||
|
|
||||||
if (grid != null && !ItemStack.isSameItemSameTags(new_state, old_state)) {
|
if (grid != null && !ItemStack.isSameItemSameTags(new, old)) {
|
||||||
if (!old_state.isEmpty) {
|
if (!old.isEmpty) {
|
||||||
old_state.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
old.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternRemoved(state!!) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_state.isEmpty) {
|
if (!new.isEmpty) {
|
||||||
new_state.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
new.getCapability(MatteryCapability.PATTERN).ifPresent { cap: IPatternStorage ->
|
||||||
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternAdded(state!!) }
|
cap.storedPatterns.forEach { state: PatternState? -> grid.onPatternAdded(state!!) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,7 +63,7 @@ class BlockEntityPatternStorage(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
updateBlockstate()
|
updateBlockstate()
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setChanged(slot, new_state, old_state)
|
super.setChanged(slot, new, old)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMaxStackSize(): Int {
|
override fun getMaxStackSize(): Int {
|
||||||
|
@ -1,31 +1,26 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity;
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent
|
||||||
|
|
||||||
public enum RedstoneSetting {
|
enum class RedstoneSetting(val label: TranslatableComponent, val description: TranslatableComponent) {
|
||||||
IGNORED(new TranslatableComponent("otm.gui.redstone.ignored"), new TranslatableComponent("otm.gui.redstone.ignored.description")),
|
IGNORED(TranslatableComponent("otm.gui.redstone.ignored"), TranslatableComponent("otm.gui.redstone.ignored.description")),
|
||||||
LOW(new TranslatableComponent("otm.gui.redstone.low"), new TranslatableComponent("otm.gui.redstone.low.description")),
|
LOW(TranslatableComponent("otm.gui.redstone.low"), TranslatableComponent("otm.gui.redstone.low.description")),
|
||||||
HIGH(new TranslatableComponent("otm.gui.redstone.high"), new TranslatableComponent("otm.gui.redstone.high.description"));
|
HIGH(TranslatableComponent("otm.gui.redstone.high"), TranslatableComponent("otm.gui.redstone.high.description"));
|
||||||
|
|
||||||
public final Component name;
|
operator fun next(): RedstoneSetting {
|
||||||
public final Component description;
|
return values[(ordinal + 1) % values.size]
|
||||||
private static final RedstoneSetting[] values = RedstoneSetting.values();
|
|
||||||
|
|
||||||
RedstoneSetting(TranslatableComponent name, TranslatableComponent description) {
|
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RedstoneSetting next() {
|
companion object {
|
||||||
return values[(ordinal() + 1) % values.length];
|
private val values = values()
|
||||||
}
|
|
||||||
|
|
||||||
public static RedstoneSetting get(int index) {
|
@JvmStatic
|
||||||
if (index < 0 || index > 2) {
|
operator fun get(index: Int): RedstoneSetting {
|
||||||
return LOW;
|
if (index !in 0 .. 2)
|
||||||
|
return LOW
|
||||||
|
|
||||||
|
return values[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
return values[index];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -54,7 +54,7 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
|||||||
val batteryLevel: Fraction
|
val batteryLevel: Fraction
|
||||||
val maxBatteryLevel: Fraction
|
val maxBatteryLevel: Fraction
|
||||||
val missingPower: Fraction
|
val missingPower: Fraction
|
||||||
get() = maxBatteryLevel - batteryLevel
|
get() = (maxBatteryLevel - batteryLevel).moreThanZero()
|
||||||
|
|
||||||
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
|
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
|
||||||
val received = receiveEnergyOuter(maxReceive, true).toInt()
|
val received = receiveEnergyOuter(maxReceive, true).toInt()
|
||||||
|
83
src/main/kotlin/ru/dbotthepony/mc/otm/container/Iterators.kt
Normal file
83
src/main/kotlin/ru/dbotthepony/mc/otm/container/Iterators.kt
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package ru.dbotthepony.mc.otm.container
|
||||||
|
|
||||||
|
import net.minecraft.world.Container
|
||||||
|
import net.minecraft.world.item.ItemStack
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
|
class ContainerIteratorItemStack(private val container: Container) : Iterator<ItemStack>, Iterable<ItemStack> {
|
||||||
|
private var index = 0
|
||||||
|
private var nextStack: ItemStack? = null
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
if (index >= container.containerSize && nextStack == null)
|
||||||
|
return false
|
||||||
|
|
||||||
|
while (nextStack == null && index < container.containerSize) {
|
||||||
|
val get = container.getItem(index)
|
||||||
|
|
||||||
|
if (!get.isEmpty) {
|
||||||
|
nextStack = get
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextStack != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): ItemStack {
|
||||||
|
val nextStack = nextStack!!
|
||||||
|
this.nextStack = null
|
||||||
|
return nextStack
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<ItemStack> {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consume(consumer: Consumer<ItemStack?>) {
|
||||||
|
for (t in this) {
|
||||||
|
consumer.accept(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContainerIteratorCapability<T>(private val container: Container, private val cap: Capability<T>) : Iterator<T>, Iterable<T> {
|
||||||
|
private var index = 0
|
||||||
|
private var nextStack: T? = null
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
if (index >= container.containerSize && nextStack == null)
|
||||||
|
return false
|
||||||
|
|
||||||
|
while (nextStack == null && index < container.containerSize) {
|
||||||
|
val get = container.getItem(index)
|
||||||
|
|
||||||
|
if (!get.isEmpty) {
|
||||||
|
get.getCapability(cap).ifPresent { t: T -> nextStack = t }
|
||||||
|
}
|
||||||
|
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextStack != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): T {
|
||||||
|
val nextStack = nextStack!!
|
||||||
|
this.nextStack = null
|
||||||
|
return nextStack
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<T> {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consume(consumer: Consumer<T>) {
|
||||||
|
for (t in this) {
|
||||||
|
consumer.accept(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,361 +1,304 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
package ru.dbotthepony.mc.otm.container
|
||||||
|
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.MethodsReturnNonnullByDefault
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import javax.annotation.ParametersAreNonnullByDefault
|
||||||
import net.minecraft.nbt.ListTag;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.nbt.ListTag
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.nbt.Tag
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.Container
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import kotlin.jvm.JvmOverloads
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity
|
||||||
|
import net.minecraftforge.common.capabilities.Capability
|
||||||
|
import ru.dbotthepony.mc.otm.ifHas
|
||||||
|
import ru.dbotthepony.mc.otm.set
|
||||||
|
import java.util.*
|
||||||
|
import java.util.function.Consumer
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
open class MatteryContainer(val watcher: Runnable, private val size: Int) : Container, Iterable<ItemStack> {
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
constructor(watcher: BlockEntity, size: Int) : this(watcher::setChanged, size)
|
||||||
import java.util.Arrays;
|
// constructor(watcher: BlockEntityMattery, size: Int) : this(watcher::setChangedLight, size)
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
private var ignoreChangeNotifications = 0
|
||||||
@ParametersAreNonnullByDefault
|
@JvmField protected val slots: Array<ItemStack> = Array(size) { ItemStack.EMPTY }
|
||||||
public class MatteryContainer implements Container, Iterable<ItemStack> {
|
private val trackedSlots: Array<ItemStack> = Array(size) { ItemStack.EMPTY }
|
||||||
protected final Runnable watcher;
|
|
||||||
protected int ignore_change_notifications = 0;
|
|
||||||
protected final int size;
|
|
||||||
protected final ItemStack[] slots;
|
|
||||||
protected final ItemStack[] tracked_slots;
|
|
||||||
|
|
||||||
public MatteryContainer(Runnable watcher, int size) {
|
final override fun getContainerSize() = size
|
||||||
this.size = size;
|
|
||||||
|
|
||||||
slots = new ItemStack[this.size];
|
fun startIgnoreUpdates() {
|
||||||
tracked_slots = new ItemStack[this.size];
|
if (++ignoreChangeNotifications == 1) {
|
||||||
Arrays.fill(slots, ItemStack.EMPTY);
|
startedIgnoringUpdates()
|
||||||
Arrays.fill(tracked_slots, ItemStack.EMPTY);
|
}
|
||||||
|
|
||||||
this.watcher = watcher;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
fun stopIgnoreUpdates() {
|
||||||
public void startIgnore() {
|
if (--ignoreChangeNotifications == 0) {
|
||||||
ignore_change_notifications++;
|
stoppedIgnoringUpdates()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
protected open fun startedIgnoringUpdates() {}
|
||||||
public void stopIgnore() {
|
protected open fun stoppedIgnoringUpdates() {}
|
||||||
ignore_change_notifications--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MatteryContainer of(@Nullable CompoundTag tag) {
|
fun deserializeNBT(tag: CompoundTag?) {
|
||||||
if (tag == null)
|
startIgnoreUpdates()
|
||||||
return this;
|
|
||||||
|
|
||||||
MatteryContainer container = MatteryContainer.of(watcher, tag, getContainerSize());
|
for (i in 0 until size) {
|
||||||
|
setItem(i, ItemStack.EMPTY)
|
||||||
if (handler != null)
|
|
||||||
container.handler = handler.cloneOf(container);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deserializeNBT(@Nullable CompoundTag tag) {
|
|
||||||
ignore_change_notifications++;
|
|
||||||
|
|
||||||
for (int i = 0; i < getContainerSize(); i++) {
|
|
||||||
setItem(i, ItemStack.EMPTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
ignore_change_notifications--;
|
stopIgnoreUpdates()
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// нам не интересен размер
|
// нам не интересен размер
|
||||||
|
tag.ifHas("items", ListTag::class.java) {
|
||||||
if (tag.get("items") instanceof ListTag list) {
|
for (i in 0 until Math.min(it.size, size)) {
|
||||||
for (int i = 0; i < Math.min(list.size(), getContainerSize()); i++) {
|
setItem(i, ItemStack.of(it[i] as CompoundTag))
|
||||||
if (list.get(i) instanceof CompoundTag get_tag) {
|
|
||||||
setItem(i, ItemStack.of(get_tag));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ignore_change_notifications--;
|
stopIgnoreUpdates()
|
||||||
setChanged();
|
setChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatteryContainer of(@Nullable Tag tag) {
|
fun deserializeNBT(tag: Tag?) {
|
||||||
if (tag == null)
|
if (tag is CompoundTag) {
|
||||||
return this;
|
deserializeNBT(tag)
|
||||||
|
|
||||||
if (tag instanceof CompoundTag compound)
|
|
||||||
return of(watcher, compound, getContainerSize());
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deserializeNBT(@Nullable Tag tag) {
|
|
||||||
if (tag == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (tag instanceof CompoundTag compound) {
|
|
||||||
deserializeNBT(compound);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContainerIteratorItemStack stackIterator() {
|
fun stacks(): ContainerIteratorItemStack {
|
||||||
return new ContainerIteratorItemStack(this);
|
return ContainerIteratorItemStack(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
fun forEachNonEmpty(consumer: (ItemStack) -> Unit) {
|
||||||
public void consumeNonEmpty(Consumer<ItemStack> consumer) {
|
for (item in slots) {
|
||||||
stackIterator().consume(consumer);
|
if (!item.isEmpty) {
|
||||||
|
consumer(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> ContainerIteratorCapability<T> capabilityIterator(Capability<T> cap) {
|
fun forEachNonEmpty(consumer: (ItemStack, Int) -> Unit) {
|
||||||
return new ContainerIteratorCapability<>(this, cap);
|
for (i in 0 until size) {
|
||||||
|
val item = slots[i]
|
||||||
|
|
||||||
|
if (!item.isEmpty) {
|
||||||
|
consumer(item, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void consumeCapability(Capability<T> cap, Consumer<T> consumer) {
|
fun <T> capabilityIterator(cap: Capability<T>): ContainerIteratorCapability<T> {
|
||||||
capabilityIterator(cap).consume(consumer);
|
return ContainerIteratorCapability(this, cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChanged(int slot, ItemStack new_state, ItemStack old_state) {
|
fun <T> consumeCapability(cap: Capability<T>, consumer: Consumer<T>) {
|
||||||
if (ignore_change_notifications == 0)
|
capabilityIterator(cap).consume(consumer)
|
||||||
watcher.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag serializeNBT() {
|
open fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
|
||||||
CompoundTag tag = new CompoundTag();
|
if (ignoreChangeNotifications == 0) watcher.run()
|
||||||
tag.putInt("size", getContainerSize());
|
|
||||||
ListTag list = new ListTag();
|
|
||||||
tag.put("items", list);
|
|
||||||
|
|
||||||
for (int i = 0; i < getContainerSize(); i++)
|
|
||||||
list.add(getItem(i).serializeNBT());
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatteryContainer of(Runnable watcher, @Nullable CompoundTag tag, int fallback_size) {
|
fun serializeNBT(): CompoundTag {
|
||||||
if (tag == null)
|
val tag = CompoundTag()
|
||||||
return new MatteryContainer(watcher, fallback_size);
|
tag["size"] = size
|
||||||
|
|
||||||
MatteryContainer container;
|
val list = ListTag()
|
||||||
|
tag["items"] = list
|
||||||
|
|
||||||
if (tag.contains("size"))
|
for (i in 0 until size)
|
||||||
container = new MatteryContainer(watcher, tag.getInt("size"));
|
list.add(this[i].serializeNBT())
|
||||||
else
|
|
||||||
container = new MatteryContainer(watcher, fallback_size);
|
|
||||||
|
|
||||||
if (tag.get("items") instanceof ListTag list)
|
return tag
|
||||||
for (int i = 0; i < Math.min(list.size(), container.getContainerSize()); i++)
|
|
||||||
if (list.get(i) instanceof CompoundTag get_tag)
|
|
||||||
container.setItem(i, ItemStack.of(get_tag));
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
fun hasEmptySlot(): Boolean {
|
||||||
public boolean hasEmptySlot() {
|
for (i in 0 until size) {
|
||||||
for (int i = 0; i < getContainerSize(); i++) {
|
if (this[i].isEmpty) {
|
||||||
if (getItem(i).isEmpty())
|
return true
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MatteryContainerHandler handler;
|
protected var handler: MatteryContainerHandler? = null
|
||||||
|
|
||||||
public MatteryContainerHandler handler(MatteryContainerInsertValidator insert_validator, MatteryContainerExtractValidator extract_validator) {
|
fun handler(
|
||||||
if (handler != null)
|
insert_validator: (Int, ItemStack) -> Boolean,
|
||||||
return handler;
|
extract_validator: (Int, Int, ItemStack) -> Boolean
|
||||||
|
): MatteryContainerHandler {
|
||||||
return handler = new MatteryContainerHandler(this, insert_validator, extract_validator);
|
return handler ?: MatteryContainerHandler(this, insert_validator, extract_validator).also { handler = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatteryContainerHandler handler(MatteryContainerInsertValidator insert_validator) {
|
fun handler(insert_validator: (Int, ItemStack) -> Boolean): MatteryContainerHandler {
|
||||||
if (handler != null)
|
return handler ?: MatteryContainerHandler(this, insert_validator).also { handler = it }
|
||||||
return handler;
|
|
||||||
|
|
||||||
return handler = new MatteryContainerHandler(this, insert_validator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatteryContainerHandler handler() {
|
fun handler(): MatteryContainerHandler {
|
||||||
if (handler != null)
|
return handler ?: MatteryContainerHandler(this).also { handler = it }
|
||||||
return handler;
|
|
||||||
|
|
||||||
return handler = new MatteryContainerHandler(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxStackSize(int slot) {
|
open fun getMaxStackSize(slot: Int) = maxStackSize
|
||||||
return getMaxStackSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack addItem(ItemStack stack, int start, int end, boolean simulate) {
|
@JvmOverloads
|
||||||
if (stack.isEmpty() || start < 0 || end > size || start >= end)
|
fun addItem(stack: ItemStack, start: Int = 0, end: Int = size, simulate: Boolean = false): ItemStack {
|
||||||
return ItemStack.EMPTY;
|
if (stack.isEmpty || start < 0 || end > size || start >= end)
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
|
||||||
final var copy = stack.copy();
|
val copy = stack.copy()
|
||||||
|
|
||||||
// двигаем в одинаковые слоты
|
// двигаем в одинаковые слоты
|
||||||
for (int slot = start; slot < end; slot++) {
|
for (slot in start until end) {
|
||||||
if (ItemStack.isSameItemSameTags(slots[slot], copy)) {
|
if (ItemStack.isSameItemSameTags(slots[slot], copy)) {
|
||||||
var this_stack = slots[slot];
|
val slotStack = slots[slot]
|
||||||
int slot_limit = Math.min(getMaxStackSize(slot), this_stack.getMaxStackSize());
|
val slotLimit = Math.min(getMaxStackSize(slot), slotStack.maxStackSize)
|
||||||
|
|
||||||
if (this_stack.getCount() < slot_limit) {
|
if (slotStack.count < slotLimit) {
|
||||||
int new_count = Math.min(this_stack.getCount() + copy.getCount(), slot_limit);
|
val newCount = Math.min(slotStack.count + copy.count, slotLimit)
|
||||||
int diff = new_count - this_stack.getCount();
|
val diff = newCount - slotStack.count
|
||||||
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
var old = this_stack.copy();
|
val old = slotStack.copy()
|
||||||
this_stack.setCount(new_count);
|
slotStack.count = newCount
|
||||||
tracked_slots[slot] = this_stack.copy();
|
trackedSlots[slot] = slotStack.copy()
|
||||||
setChanged(slot, this_stack, old);
|
setChanged(slot, slotStack, old)
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.shrink(diff);
|
copy.shrink(diff)
|
||||||
|
|
||||||
if (copy.isEmpty()) {
|
if (copy.isEmpty) {
|
||||||
return copy;
|
return copy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// двигаем в пустые слоты
|
// двигаем в пустые слоты
|
||||||
for (int slot = start; slot < end; slot++) {
|
for (slot in start until end) {
|
||||||
if (slots[slot].isEmpty()) {
|
if (slots[slot].isEmpty) {
|
||||||
int diff = Math.min(copy.getCount(), Math.min(getMaxStackSize(slot), copy.getMaxStackSize()));
|
val diff = Math.min(copy.count, Math.min(getMaxStackSize(slot), copy.maxStackSize))
|
||||||
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
var put_copy = copy.copy();
|
val copyToPut = copy.copy()
|
||||||
put_copy.setCount(diff);
|
copyToPut.count = diff
|
||||||
slots[slot] = put_copy;
|
this[slot] = copyToPut
|
||||||
tracked_slots[slot] = put_copy.copy();
|
|
||||||
setChanged(slot, put_copy, ItemStack.EMPTY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.shrink(diff);
|
copy.shrink(diff)
|
||||||
|
|
||||||
if (copy.isEmpty()) {
|
if (copy.isEmpty) {
|
||||||
return copy;
|
return copy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
fun addItem(stack: ItemStack, simulate: Boolean): ItemStack {
|
||||||
public ItemStack addItem(ItemStack stack, boolean simulate) {
|
return addItem(stack, 0, size, simulate)
|
||||||
return addItem(stack, 0, size, simulate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@JvmOverloads
|
||||||
public ItemStack addItem(ItemStack stack) {
|
fun fullyAddItem(stack: ItemStack, start: Int = 0, end: Int = size): Boolean {
|
||||||
return addItem(stack, 0, size, false);
|
if (!addItem(stack, start, end, true).isEmpty)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return addItem(stack, start, end, false).isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean fullyAddItem(ItemStack stack) {
|
override fun isEmpty(): Boolean {
|
||||||
if (!addItem(stack, 0, size, true).isEmpty()) {
|
for (stack in slots)
|
||||||
return false;
|
if (!stack.isEmpty)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(slot: Int) = getItem(slot)
|
||||||
|
operator fun set(slot: Int, stack: ItemStack) = setItem(slot, stack)
|
||||||
|
|
||||||
|
operator fun contains(other: ItemStack): Boolean {
|
||||||
|
for (i in 0 until size) {
|
||||||
|
if (ItemStack.isSameItemSameTags(this[i], other)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return addItem(stack, 0, size, false).isEmpty();
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
final override fun getItem(slot: Int): ItemStack {
|
||||||
public boolean fullyAddItem(ItemStack stack, int start, int end) {
|
val item = slots[slot]
|
||||||
if (!addItem(stack, start, end, true).isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return addItem(stack, start, end, false).isEmpty();
|
if (item.isEmpty)
|
||||||
|
return ItemStack.EMPTY
|
||||||
|
else
|
||||||
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun removeItem(slot: Int, amount: Int): ItemStack {
|
||||||
public int getContainerSize() {
|
if (amount <= 0 || slot < 0 || slot >= size || slots[slot].isEmpty)
|
||||||
return size;
|
return ItemStack.EMPTY
|
||||||
|
|
||||||
|
val old = slots[slot].copy()
|
||||||
|
val split = slots[slot].split(amount)
|
||||||
|
trackedSlots[slot] = slots[slot].copy()
|
||||||
|
setChanged(slot, if (slots[slot].isEmpty) ItemStack.EMPTY else slots[slot], old)
|
||||||
|
|
||||||
|
return split
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun removeItemNoUpdate(slot: Int): ItemStack {
|
||||||
public boolean isEmpty() {
|
val old = slots[slot]
|
||||||
for (var stack : slots)
|
slots[slot] = ItemStack.EMPTY
|
||||||
if (!stack.isEmpty())
|
trackedSlots[slot] = ItemStack.EMPTY
|
||||||
return false;
|
return old
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun setItem(slot: Int, stack: ItemStack) {
|
||||||
public ItemStack getItem(int slot) {
|
if (slots[slot].isEmpty && stack.isEmpty || stack === slots[slot])
|
||||||
return slots[slot].isEmpty() ? ItemStack.EMPTY : slots[slot];
|
return
|
||||||
|
|
||||||
|
val old = slots[slot]
|
||||||
|
slots[slot] = stack
|
||||||
|
trackedSlots[slot] = stack.copy()
|
||||||
|
setChanged(slot, stack, old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun setChanged() {
|
||||||
public ItemStack removeItem(int slot, int amount) {
|
for (slot in 0 until size) {
|
||||||
if (amount <= 0 || slot < 0 || slot >= size || slots[slot].isEmpty())
|
if (!ItemStack.isSameItemSameTags(slots[slot], trackedSlots[slot])) {
|
||||||
return ItemStack.EMPTY;
|
setChanged(slot, slots[slot], trackedSlots[slot])
|
||||||
|
trackedSlots[slot] = slots[slot].copy()
|
||||||
var old = slots[slot].copy();
|
|
||||||
var split = slots[slot].split(amount);
|
|
||||||
tracked_slots[slot] = slots[slot].copy();
|
|
||||||
setChanged(slot, slots[slot].isEmpty() ? ItemStack.EMPTY : slots[slot], old);
|
|
||||||
|
|
||||||
return split;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack removeItemNoUpdate(int slot) {
|
|
||||||
var old = slots[slot];
|
|
||||||
slots[slot] = ItemStack.EMPTY;
|
|
||||||
tracked_slots[slot] = ItemStack.EMPTY;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setItem(int slot, ItemStack stack) {
|
|
||||||
if (slots[slot].isEmpty() && stack.isEmpty() || stack == slots[slot])
|
|
||||||
return;
|
|
||||||
|
|
||||||
var old = slots[slot];
|
|
||||||
slots[slot] = stack;
|
|
||||||
tracked_slots[slot] = stack.copy();
|
|
||||||
setChanged(slot, stack, old);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setChanged() {
|
|
||||||
for (int slot = 0; slot < size; slot++) {
|
|
||||||
if (!ItemStack.isSameItemSameTags(slots[slot], tracked_slots[slot])) {
|
|
||||||
setChanged(slot, slots[slot], tracked_slots[slot]);
|
|
||||||
tracked_slots[slot] = slots[slot].copy();
|
|
||||||
// mojang соси))0)0))0)))))0)
|
// mojang соси))0)0))0)))))0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun stillValid(player: Player): Boolean {
|
||||||
public boolean stillValid(Player player) {
|
return true
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun clearContent() {
|
||||||
public void clearContent() {
|
for (slot in 0 until size) {
|
||||||
for (int slot = 0; slot < size; slot++) {
|
if (!slots[slot].isEmpty) {
|
||||||
if (!slots[slot].isEmpty()) {
|
val old = slots[slot]
|
||||||
setChanged(slot, ItemStack.EMPTY, slots[slot]);
|
slots[slot] = ItemStack.EMPTY
|
||||||
|
setChanged(slot, ItemStack.EMPTY, old)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrays.fill(tracked_slots, ItemStack.EMPTY);
|
Arrays.fill(trackedSlots, ItemStack.EMPTY)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
final override fun iterator(): Iterator<ItemStack> {
|
||||||
public Iterator<ItemStack> iterator() {
|
return slots.iterator()
|
||||||
return Arrays.stream(slots).iterator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,132 +1,93 @@
|
|||||||
package ru.dbotthepony.mc.otm.container;
|
package ru.dbotthepony.mc.otm.container
|
||||||
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
class MatteryContainerHandler @JvmOverloads internal constructor(
|
||||||
|
private val container: MatteryContainer,
|
||||||
|
private val insert_validator: (Int, ItemStack) -> Boolean = { _: Int, _: ItemStack -> true },
|
||||||
|
private val extract_validator: (Int, Int, ItemStack) -> Boolean = { _: Int, _: Int, _: ItemStack -> true }
|
||||||
|
) : IItemHandler {
|
||||||
|
private var handler = LazyOptional.of<IItemHandler> { this }
|
||||||
|
|
||||||
public class MatteryContainerHandler implements IItemHandler {
|
fun get(): LazyOptional<IItemHandler> {
|
||||||
private final MatteryContainer container;
|
return handler
|
||||||
private final MatteryContainerInsertValidator insert_validator;
|
|
||||||
private final MatteryContainerExtractValidator extract_validator;
|
|
||||||
|
|
||||||
MatteryContainerHandler(MatteryContainer container, MatteryContainerInsertValidator insert_validator, MatteryContainerExtractValidator extract_validator) {
|
|
||||||
this.container = container;
|
|
||||||
this.insert_validator = insert_validator;
|
|
||||||
this.extract_validator = extract_validator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MatteryContainerHandler(MatteryContainer container) {
|
fun invalidate() {
|
||||||
this(container, (slot, stack) -> true, (slot, amount, stack) -> true);
|
handler.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
MatteryContainerHandler(MatteryContainer container, MatteryContainerInsertValidator insert_validator) {
|
fun revive() {
|
||||||
this(container, insert_validator, (slot, amount, stack) -> true);
|
handler = LazyOptional.of { this }
|
||||||
}
|
}
|
||||||
|
|
||||||
private LazyOptional<IItemHandler> handler = LazyOptional.of(() -> this);
|
override fun getSlots() = container.containerSize
|
||||||
|
override fun getStackInSlot(slot: Int) = container[slot]
|
||||||
|
|
||||||
public LazyOptional<IItemHandler> get() {
|
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
|
||||||
return handler;
|
if (!insert_validator(slot, stack))
|
||||||
}
|
return stack
|
||||||
|
|
||||||
public void invalidate() {
|
val localStack = container[slot]
|
||||||
handler.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void revive() {
|
if (localStack.isEmpty) {
|
||||||
handler = LazyOptional.of(() -> this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSlots() {
|
|
||||||
return container.getContainerSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ItemStack getStackInSlot(int slot) {
|
|
||||||
return container.getItem(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
|
||||||
if (!insert_validator.apply(slot, stack))
|
|
||||||
return stack;
|
|
||||||
|
|
||||||
ItemStack self_stack = container.getItem(slot);
|
|
||||||
|
|
||||||
if (self_stack.isEmpty()) {
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
var copy = stack.copy();
|
val copy = stack.copy()
|
||||||
container.setChanged(slot, copy, ItemStack.EMPTY);
|
container.setChanged(slot, copy, ItemStack.EMPTY)
|
||||||
container.setItem(slot, copy);
|
container.setItem(slot, copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY
|
||||||
} else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) {
|
} else if (localStack.isStackable && localStack.maxStackSize > localStack.count && ItemStack.isSameItemSameTags(localStack, stack)) {
|
||||||
int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount());
|
val newCount = Math.min(localStack.maxStackSize, localStack.count + stack.count)
|
||||||
int diff = new_count - self_stack.getCount();
|
val diff = newCount - localStack.count
|
||||||
|
|
||||||
if (diff != 0) {
|
if (diff != 0) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
ItemStack copy_self = self_stack.copy();
|
val copy = localStack.copy()
|
||||||
self_stack.grow(diff);
|
localStack.grow(diff)
|
||||||
container.setChanged(slot, self_stack, copy_self);
|
container.setChanged(slot, localStack, copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack copy = stack.copy();
|
val copy = stack.copy()
|
||||||
copy.shrink(diff);
|
copy.shrink(diff)
|
||||||
return copy;
|
return copy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack;
|
return stack
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack {
|
||||||
@Override
|
|
||||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
|
||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY
|
||||||
|
|
||||||
if (amount < 0)
|
require(amount >= 0) { "Can not extract negative amount of items" }
|
||||||
throw new IllegalArgumentException("Can not extract negative amount of items");
|
|
||||||
|
|
||||||
ItemStack self_stack = container.getItem(slot);
|
val localStack = container.getItem(slot)
|
||||||
|
if (localStack.isEmpty) return ItemStack.EMPTY
|
||||||
|
if (!extract_validator(slot, amount, localStack)) return ItemStack.EMPTY
|
||||||
|
|
||||||
if (self_stack.isEmpty())
|
val minimal = Math.min(amount, localStack.count)
|
||||||
return ItemStack.EMPTY;
|
val copy = localStack.copy()
|
||||||
|
copy.count = minimal
|
||||||
if (!extract_validator.apply(slot, amount, self_stack))
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
|
|
||||||
int minimal = Math.min(amount, self_stack.getCount());
|
|
||||||
ItemStack copy = self_stack.copy();
|
|
||||||
copy.setCount(minimal);
|
|
||||||
|
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
ItemStack copy_self = self_stack.copy();
|
val copy = localStack.copy()
|
||||||
self_stack.shrink(minimal);
|
localStack.shrink(minimal)
|
||||||
container.setChanged(slot, self_stack, copy_self);
|
container.setChanged(slot, localStack, copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getSlotLimit(slot: Int): Int {
|
||||||
public int getSlotLimit(int slot) {
|
return container.maxStackSize
|
||||||
return container.getMaxStackSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
|
||||||
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
|
return insert_validator(slot, stack)
|
||||||
return insert_validator.apply(slot, stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
MatteryContainerHandler cloneOf(MatteryContainer container) {
|
|
||||||
return new MatteryContainerHandler(container, insert_validator, extract_validator);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,12 +57,12 @@ abstract class Abstract6Graph<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun <T, G : Abstract6Graph<T>> discoverFull(
|
fun <T> discoverFull(
|
||||||
level: ServerLevel,
|
level: ServerLevel,
|
||||||
blockPos: BlockPos,
|
blockPos: BlockPos,
|
||||||
node: Graph6Node<T>,
|
node: Graph6Node<T>,
|
||||||
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
||||||
factory: () -> G
|
factory: () -> Abstract6Graph<T>
|
||||||
) {
|
) {
|
||||||
OverdriveThatMatters.tickUntil(level) {
|
OverdriveThatMatters.tickUntil(level) {
|
||||||
!node.valid || discover(level, blockPos, node, nodeGetter, factory)
|
!node.valid || discover(level, blockPos, node, nodeGetter, factory)
|
||||||
@ -70,12 +70,12 @@ abstract class Abstract6Graph<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun <T, G : Abstract6Graph<T>> discover(
|
fun <T> discover(
|
||||||
level: ServerLevel,
|
level: ServerLevel,
|
||||||
blockPos: BlockPos,
|
blockPos: BlockPos,
|
||||||
node: Graph6Node<T>,
|
node: Graph6Node<T>,
|
||||||
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
nodeGetter: (BlockEntity) -> Graph6Node<T>?,
|
||||||
factory: () -> G
|
factory: () -> Abstract6Graph<T>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
var fullDiscovery = true
|
var fullDiscovery = true
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ abstract class PoweredMatteryMenu protected constructor(
|
|||||||
batterySlot = BatterySlot(SimpleContainer(1), 0)
|
batterySlot = BatterySlot(SimpleContainer(1), 0)
|
||||||
} else {
|
} else {
|
||||||
powerWidget = LevelGaugeWidget(this, tile.getCapability(MatteryCapability.ENERGY).resolve().get())
|
powerWidget = LevelGaugeWidget(this, tile.getCapability(MatteryCapability.ENERGY).resolve().get())
|
||||||
batterySlot = BatterySlot(tile.battery_container, 0)
|
batterySlot = BatterySlot(tile.batteryContainer, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user