Add compat for metamachine and create arm
This commit is contained in:
@@ -9,6 +9,7 @@ import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
||||
import com.imbgt.kineticbridge.compat.create.KineticBridgeCreateCompat;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -23,6 +24,7 @@ public class KineticBridge {
|
||||
IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
REGISTRATE.registerRegistrate();
|
||||
KineticBridgeCreateCompat.init(modBus);
|
||||
|
||||
modBus.addGenericListener(MachineDefinition.class, this::registerMachines);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.imbgt.kineticbridge.compat.create;
|
||||
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
import com.imbgt.kineticbridge.KineticBridge;
|
||||
import com.imbgt.kineticbridge.compat.create.arm.MetaMachineArmInteractionPointType;
|
||||
import com.simibubi.create.api.registry.CreateRegistries;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
|
||||
public final class KineticBridgeCreateCompat {
|
||||
|
||||
private static final DeferredRegister<ArmInteractionPointType> ARM_POINTS = DeferredRegister
|
||||
.create(CreateRegistries.ARM_INTERACTION_POINT_TYPE, KineticBridge.MOD_ID);
|
||||
|
||||
public static final RegistryObject<ArmInteractionPointType> META_MACHINE_POINT = ARM_POINTS.register("meta_machine",
|
||||
MetaMachineArmInteractionPointType::new);
|
||||
|
||||
private KineticBridgeCreateCompat() {}
|
||||
|
||||
public static void init(IEventBus modBus) {
|
||||
ARM_POINTS.register(modBus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.imbgt.kineticbridge.compat.create.arm;
|
||||
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPoint;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetaMachineArmInteractionPoint extends ArmInteractionPoint {
|
||||
|
||||
public MetaMachineArmInteractionPoint(ArmInteractionPointType type, Level level,
|
||||
BlockPos pos, BlockState state) {
|
||||
super(type, level, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||
if (mode != Mode.DEPOSIT) {
|
||||
return stack;
|
||||
}
|
||||
IItemHandler handler = getHandler();
|
||||
if (handler == null) {
|
||||
return stack;
|
||||
}
|
||||
return ItemHandlerHelper.insertItem(handler, stack, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extract(int slot, int amount, boolean simulate) {
|
||||
if (mode != Mode.TAKE) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
IItemHandler handler = getHandler();
|
||||
if (handler == null) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return handler.extractItem(slot, amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotCount() {
|
||||
if (mode != Mode.TAKE) {
|
||||
return 0;
|
||||
}
|
||||
IItemHandler handler = getHandler();
|
||||
return handler == null ? 0 : handler.getSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IItemHandler getHandler() {
|
||||
if (!cachedHandler.isPresent()) {
|
||||
var be = level.getBlockEntity(pos);
|
||||
if (!(be instanceof MetaMachineBlockEntity metaMachine)) {
|
||||
cachedHandler = LazyOptional.empty();
|
||||
return null;
|
||||
}
|
||||
|
||||
List<IItemHandler> handlers = new ArrayList<>();
|
||||
List<LazyOptional<IItemHandler>> dependencies = new ArrayList<>();
|
||||
Map<IItemHandler, Boolean> seen = new IdentityHashMap<>();
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
LazyOptional<IItemHandler> sideCapability = metaMachine.getCapability(ForgeCapabilities.ITEM_HANDLER,
|
||||
direction);
|
||||
sideCapability.ifPresent(handler -> {
|
||||
if (handler.getSlots() > 0 && !seen.containsKey(handler)) {
|
||||
handlers.add(handler);
|
||||
dependencies.add(sideCapability);
|
||||
seen.put(handler, Boolean.TRUE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (handlers.isEmpty()) {
|
||||
cachedHandler = metaMachine.getCapability(ForgeCapabilities.ITEM_HANDLER, null);
|
||||
} else if (handlers.size() == 1) {
|
||||
IItemHandler handler = handlers.get(0);
|
||||
LazyOptional<IItemHandler> aggregated = LazyOptional.of(() -> handler);
|
||||
dependencies.forEach(opt -> opt.addListener(l -> aggregated.invalidate()));
|
||||
cachedHandler = aggregated;
|
||||
} else {
|
||||
AggregatedItemHandler aggregatedHandler = new AggregatedItemHandler(handlers);
|
||||
LazyOptional<IItemHandler> aggregated = LazyOptional.of(() -> aggregatedHandler);
|
||||
dependencies.forEach(opt -> opt.addListener(l -> aggregated.invalidate()));
|
||||
cachedHandler = aggregated;
|
||||
}
|
||||
}
|
||||
return cachedHandler.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCachedState() {
|
||||
var previous = cachedState;
|
||||
super.updateCachedState();
|
||||
if (!previous.equals(cachedState) && cachedHandler.isPresent()) {
|
||||
cachedHandler.invalidate();
|
||||
cachedHandler = LazyOptional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static class AggregatedItemHandler implements IItemHandler {
|
||||
|
||||
private final List<IItemHandler> delegates;
|
||||
|
||||
private AggregatedItemHandler(List<IItemHandler> delegates) {
|
||||
this.delegates = List.copyOf(delegates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
int total = 0;
|
||||
for (IItemHandler handler : delegates) {
|
||||
total += handler.getSlots();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
int index = slot;
|
||||
for (IItemHandler handler : delegates) {
|
||||
int size = handler.getSlots();
|
||||
if (index < size) {
|
||||
return handler.getStackInSlot(index);
|
||||
}
|
||||
index -= size;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
int index = slot;
|
||||
for (IItemHandler handler : delegates) {
|
||||
int size = handler.getSlots();
|
||||
if (index < size) {
|
||||
return handler.insertItem(index, stack, simulate);
|
||||
}
|
||||
index -= size;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
int index = slot;
|
||||
for (IItemHandler handler : delegates) {
|
||||
int size = handler.getSlots();
|
||||
if (index < size) {
|
||||
return handler.extractItem(index, amount, simulate);
|
||||
}
|
||||
index -= size;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
int index = slot;
|
||||
for (IItemHandler handler : delegates) {
|
||||
int size = handler.getSlots();
|
||||
if (index < size) {
|
||||
return handler.getSlotLimit(index);
|
||||
}
|
||||
index -= size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
int index = slot;
|
||||
for (IItemHandler handler : delegates) {
|
||||
int size = handler.getSlots();
|
||||
if (index < size) {
|
||||
return handler.isItemValid(index, stack);
|
||||
}
|
||||
index -= size;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.imbgt.kineticbridge.compat.create.arm;
|
||||
|
||||
import com.gregtechceu.gtceu.api.block.MetaMachineBlock;
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPoint;
|
||||
import com.simibubi.create.content.kinetics.mechanicalArm.ArmInteractionPointType;
|
||||
|
||||
public class MetaMachineArmInteractionPointType extends ArmInteractionPointType {
|
||||
|
||||
@Override
|
||||
public boolean canCreatePoint(Level level, BlockPos pos, BlockState state) {
|
||||
if (!(state.getBlock() instanceof MetaMachineBlock)) {
|
||||
return false;
|
||||
}
|
||||
var be = level.getBlockEntity(pos);
|
||||
if (!(be instanceof MetaMachineBlockEntity metaMachine)) {
|
||||
return false;
|
||||
}
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (metaMachine.getCapability(ForgeCapabilities.ITEM_HANDLER, direction).isPresent()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return metaMachine.getCapability(ForgeCapabilities.ITEM_HANDLER, null).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmInteractionPoint createPoint(Level level, BlockPos pos, BlockState state) {
|
||||
return new MetaMachineArmInteractionPoint(this, level, pos, state);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user