Patterns, Pattern Storages and Matter Scanner!

This commit is contained in:
DBotThePony 2021-08-16 11:45:55 +07:00
parent 9e2d2db711
commit aedb169eca
Signed by: DBot
GPG Key ID: DCC23B5715498507
36 changed files with 1645 additions and 184 deletions

View File

@ -7,6 +7,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import javax.annotation.Nullable;
@ -17,10 +18,21 @@ public interface IMatterGridCell {
@Nullable
IMatterHandler getMatterHandler();
@Nullable
IPatternStorage getPatternStorage();
boolean isValidMatterCell();
void setMatterGrid(MatterGrid grid);
default void notifyPatternsChanged() {
}
default void scheduleDiscoverNeighbours(BlockPos pos, Level level) {
MatterGrid.scheduleDiscoverNeighbours(this, pos, level);
}
default boolean connectOrCreateMatterGrid(BlockPos pos, Level level) {
return connectOrCreateMatterGrid(pos, level, false);
}

View File

@ -1,17 +1,23 @@
package ru.dbotthepony.mc.otm;
import com.google.common.collect.ImmutableList;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartedEvent;
import net.minecraftforge.fmlserverevents.FMLServerStoppingEvent;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class MatterGrid {
@ -192,6 +198,95 @@ public class MatterGrid {
return received;
}
public boolean insertPattern(IPatternStorage.PatternState state, boolean only_update, boolean simulate) {
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
if (storage.insertPattern(state, true, simulate)) {
return true;
}
}
}
if (only_update)
return false;
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
if (storage.insertPattern(state, false, simulate)) {
return true;
}
}
}
return false;
}
public Collection<IPatternStorage.PatternState> getStoredPatterns() {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>();
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
list.addAll(storage.getStoredPatterns());
}
}
return ImmutableList.copyOf(list);
}
public Collection<IPatternStorage.PatternState> findPattern(Item item) {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>();
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
list.addAll(storage.findPattern(item));
}
}
return ImmutableList.copyOf(list);
}
public Collection<IPatternStorage.PatternState> findPattern(Predicate<IPatternStorage.PatternState> item) {
ArrayList<IPatternStorage.PatternState> list = new ArrayList<>();
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
list.addAll(storage.findPattern(item));
}
}
return ImmutableList.copyOf(list);
}
@Nullable
public IPatternStorage findExactPatternStorage(IPatternStorage.PatternState state) {
for (IMatterGridCell cell : cells) {
IPatternStorage storage = cell.getPatternStorage();
if (storage != null) {
if (storage.hasExactPattern(state)) {
return storage;
}
}
}
return null;
}
public void notifyPatternsChanged() {
for (IMatterGridCell cell : cells)
cell.notifyPatternsChanged();
}
public void track(IMatterGridCell entity) {
if (cells.contains(entity))
return;

View File

@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.block.*;
import ru.dbotthepony.mc.otm.block.entity.*;
import ru.dbotthepony.mc.otm.item.ItemBattery;
import ru.dbotthepony.mc.otm.item.ItemMatterCapacitor;
import ru.dbotthepony.mc.otm.item.ItemPatternStorage;
import ru.dbotthepony.mc.otm.item.ItemPill;
import ru.dbotthepony.mc.otm.menu.*;
import ru.dbotthepony.mc.otm.screen.*;
@ -36,6 +37,8 @@ public class Registry {
public static final ResourceLocation MATTER_DECOMPOSER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_decomposer");
public static final ResourceLocation MATTER_CAPACITOR_BANK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_capacitor_bank");
public static final ResourceLocation MATTER_CABLE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_cable");
public static final ResourceLocation PATTERN_STORAGE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pattern_storage");
public static final ResourceLocation MATTER_SCANNER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_scanner");
public static final ResourceLocation ANDROID_CAPABILITY = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_capability");
@ -51,6 +54,8 @@ public class Registry {
public static final ResourceLocation MATTER_CAPACITOR_NORMAL = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_capacitor_normal");
public static final ResourceLocation MATTER_CAPACITOR_CREATIVE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_capacitor_creative");
public static final ResourceLocation PATTERN_DRIVE_NORMAL = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pattern_drive_normal");
}
public static class Blocks {
@ -59,6 +64,8 @@ public class Registry {
public static final Block MATTER_DECOMPOSER = new BlockMatterDecomposer();
public static final Block MATTER_CAPACITOR_BANK = new BlockMatterCapacitorBank();
public static final Block MATTER_CABLE = new BlockMatterCable();
public static final Block PATTERN_STORAGE = new BlockPatternStorage();
public static final Block MATTER_SCANNER = new BlockMatterScanner();
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -66,6 +73,8 @@ public class Registry {
MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER);
MATTER_CAPACITOR_BANK.setRegistryName(Names.MATTER_CAPACITOR_BANK);
MATTER_CABLE.setRegistryName(Names.MATTER_CABLE);
PATTERN_STORAGE.setRegistryName(Names.PATTERN_STORAGE);
MATTER_SCANNER.setRegistryName(Names.MATTER_SCANNER);
}
public static void register(final RegistryEvent.Register<Block> event) {
@ -74,6 +83,8 @@ public class Registry {
event.getRegistry().register(MATTER_DECOMPOSER);
event.getRegistry().register(MATTER_CAPACITOR_BANK);
event.getRegistry().register(MATTER_CABLE);
event.getRegistry().register(PATTERN_STORAGE);
event.getRegistry().register(MATTER_SCANNER);
// OverdriveThatMatters.LOGGER.info("Registered blocks");
}
@ -85,6 +96,8 @@ public class Registry {
public static final Item MATTER_DECOMPOSER = new BlockItem(Blocks.MATTER_DECOMPOSER, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC));
public static final Item MATTER_CAPACITOR_BANK = new BlockItem(Blocks.MATTER_CAPACITOR_BANK, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC));
public static final Item MATTER_CABLE = new BlockItem(Blocks.MATTER_CABLE, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC));
public static final Item PATTERN_STORAGE = new BlockItem(Blocks.PATTERN_STORAGE, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC));
public static final Item MATTER_SCANNER = new BlockItem(Blocks.MATTER_SCANNER, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC));
public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID);
public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE);
@ -99,12 +112,16 @@ public class Registry {
public static final ItemMatterCapacitor MATTER_CAPACITOR_NORMAL = new ItemMatterCapacitor(new BigDecimal("10"));
public static final ItemMatterCapacitor MATTER_CAPACITOR_CREATIVE = new ItemMatterCapacitor();
public static final ItemPatternStorage PATTERN_DRIVE_NORMAL = new ItemPatternStorage(4);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
BATTERY_BANK.setRegistryName(Names.BATTERY_BANK);
MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER);
MATTER_CAPACITOR_BANK.setRegistryName(Names.MATTER_CAPACITOR_BANK);
MATTER_CABLE.setRegistryName(Names.MATTER_CABLE);
PATTERN_STORAGE.setRegistryName(Names.PATTERN_STORAGE);
MATTER_SCANNER.setRegistryName(Names.MATTER_SCANNER);
PILL_ANDROID.setRegistryName(Names.PILL_ANDROID);
PILL_HUMANE.setRegistryName(Names.PILL_HUMANE);
@ -117,6 +134,8 @@ public class Registry {
MATTER_CAPACITOR_NORMAL.setRegistryName(Names.MATTER_CAPACITOR_NORMAL);
MATTER_CAPACITOR_CREATIVE.setRegistryName(Names.MATTER_CAPACITOR_CREATIVE);
PATTERN_DRIVE_NORMAL.setRegistryName(Names.PATTERN_DRIVE_NORMAL);
}
public static void register(final RegistryEvent.Register<Item> event) {
@ -125,6 +144,8 @@ public class Registry {
event.getRegistry().register(MATTER_DECOMPOSER);
event.getRegistry().register(MATTER_CAPACITOR_BANK);
event.getRegistry().register(MATTER_CABLE);
event.getRegistry().register(PATTERN_STORAGE);
event.getRegistry().register(MATTER_SCANNER);
event.getRegistry().register(PILL_ANDROID);
event.getRegistry().register(PILL_HUMANE);
@ -138,16 +159,20 @@ public class Registry {
event.getRegistry().register(MATTER_CAPACITOR_NORMAL);
event.getRegistry().register(MATTER_CAPACITOR_CREATIVE);
event.getRegistry().register(PATTERN_DRIVE_NORMAL);
// OverdriveThatMatters.LOGGER.info("Registered items");
}
}
public static class BlockEntities {
public static BlockEntityType<BlockEntityAndroidStation> ANDROID_STATION = BlockEntityType.Builder.of(BlockEntityAndroidStation::new, Blocks.ANDROID_STATION).build(null);
public static BlockEntityType<BlockEntityBatteryBank> BATTERY_BANK = BlockEntityType.Builder.of(BlockEntityBatteryBank::new, Blocks.BATTERY_BANK).build(null);
public static BlockEntityType<BlockEntityMatterDecomposer> MATTER_DECOMPOSER = BlockEntityType.Builder.of(BlockEntityMatterDecomposer::new, Blocks.MATTER_DECOMPOSER).build(null);
public static BlockEntityType<BlockEntityMatterCapacitorBank> MATTER_CAPACITOR_BANK = BlockEntityType.Builder.of(BlockEntityMatterCapacitorBank::new, Blocks.MATTER_CAPACITOR_BANK).build(null);
public static BlockEntityType<BlockEntityMatterCable> MATTER_CABLE = BlockEntityType.Builder.of(BlockEntityMatterCable::new, Blocks.MATTER_CABLE).build(null);
public static final BlockEntityType<BlockEntityAndroidStation> ANDROID_STATION = BlockEntityType.Builder.of(BlockEntityAndroidStation::new, Blocks.ANDROID_STATION).build(null);
public static final BlockEntityType<BlockEntityBatteryBank> BATTERY_BANK = BlockEntityType.Builder.of(BlockEntityBatteryBank::new, Blocks.BATTERY_BANK).build(null);
public static final BlockEntityType<BlockEntityMatterDecomposer> MATTER_DECOMPOSER = BlockEntityType.Builder.of(BlockEntityMatterDecomposer::new, Blocks.MATTER_DECOMPOSER).build(null);
public static final BlockEntityType<BlockEntityMatterCapacitorBank> MATTER_CAPACITOR_BANK = BlockEntityType.Builder.of(BlockEntityMatterCapacitorBank::new, Blocks.MATTER_CAPACITOR_BANK).build(null);
public static final BlockEntityType<BlockEntityMatterCable> MATTER_CABLE = BlockEntityType.Builder.of(BlockEntityMatterCable::new, Blocks.MATTER_CABLE).build(null);
public static final BlockEntityType<BlockEntityPatternStorage> PATTERN_STORAGE = BlockEntityType.Builder.of(BlockEntityPatternStorage::new, Blocks.PATTERN_STORAGE).build(null);
public static final BlockEntityType<BlockEntityMatterScanner> MATTER_SCANNER = BlockEntityType.Builder.of(BlockEntityMatterScanner::new, Blocks.MATTER_SCANNER).build(null);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
@ -155,6 +180,8 @@ public class Registry {
MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER);
MATTER_CAPACITOR_BANK.setRegistryName(Names.MATTER_CAPACITOR_BANK);
MATTER_CABLE.setRegistryName(Names.MATTER_CABLE);
PATTERN_STORAGE.setRegistryName(Names.PATTERN_STORAGE);
MATTER_SCANNER.setRegistryName(Names.MATTER_SCANNER);
}
public static void register(final RegistryEvent.Register<BlockEntityType<?>> event) {
@ -163,6 +190,8 @@ public class Registry {
event.getRegistry().register(MATTER_DECOMPOSER);
event.getRegistry().register(MATTER_CAPACITOR_BANK);
event.getRegistry().register(MATTER_CABLE);
event.getRegistry().register(PATTERN_STORAGE);
event.getRegistry().register(MATTER_SCANNER);
// OverdriveThatMatters.LOGGER.info("Registered block entities");
}
@ -173,12 +202,16 @@ public class Registry {
public static final MenuType<BatteryBankMenu> BATTERY_BANK = new MenuType<>(BatteryBankMenu::new);
public static final MenuType<MatterDecomposerMenu> MATTER_DECOMPOSER = new MenuType<>(MatterDecomposerMenu::new);
public static final MenuType<MatterCapacitorBankMenu> MATTER_CAPACITOR_BANK = new MenuType<>(MatterCapacitorBankMenu::new);
public static final MenuType<PatternStorageMenu> PATTERN_STORAGE = new MenuType<>(PatternStorageMenu::new);
public static final MenuType<MatterScannerMenu> MATTER_SCANNER = new MenuType<>(MatterScannerMenu::new);
static {
ANDROID_STATION.setRegistryName(Names.ANDROID_STATION);
BATTERY_BANK.setRegistryName(Names.BATTERY_BANK);
MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER);
MATTER_CAPACITOR_BANK.setRegistryName(Names.MATTER_CAPACITOR_BANK);
PATTERN_STORAGE.setRegistryName(Names.PATTERN_STORAGE);
MATTER_SCANNER.setRegistryName(Names.MATTER_SCANNER);
}
public static void register(final RegistryEvent.Register<MenuType<?>> event) {
@ -186,6 +219,8 @@ public class Registry {
event.getRegistry().register(BATTERY_BANK);
event.getRegistry().register(MATTER_DECOMPOSER);
event.getRegistry().register(MATTER_CAPACITOR_BANK);
event.getRegistry().register(PATTERN_STORAGE);
event.getRegistry().register(MATTER_SCANNER);
// OverdriveThatMatters.LOGGER.info("Registered menus");
}
@ -195,6 +230,8 @@ public class Registry {
MenuScreens.register(BATTERY_BANK, BatteryBankScreen::new);
MenuScreens.register(MATTER_DECOMPOSER, MatterDecomposerScreen::new);
MenuScreens.register(MATTER_CAPACITOR_BANK, MatterCapacitorBankScreen::new);
MenuScreens.register(PATTERN_STORAGE, PatternStorageScreen::new);
MenuScreens.register(MATTER_SCANNER, MatterScannerScreen::new);
// OverdriveThatMatters.LOGGER.info("Registered screens");
}

View File

@ -0,0 +1,28 @@
package ru.dbotthepony.mc.otm.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPoweredWorker;
import javax.annotation.Nullable;
public class BlockMatterScanner extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityMatterScanner(blockPos, blockState);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_SCANNER ? null : BlockEntityMatteryPoweredWorker::basicTicker;
}
}

View File

@ -0,0 +1,17 @@
package ru.dbotthepony.mc.otm.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage;
import javax.annotation.Nullable;
public class BlockPatternStorage extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityPatternStorage(blockPos, blockState);
}
}

View File

@ -44,7 +44,7 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPowered impleme
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityAndroidStation tile) {
tile.tickBatteryCharge();
tile.batteryChargeLoop();
BlockPos pos = tile.getBlockPos();
List<LivingEntity> entities = tile.getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1));

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.container.SimpleSerializableContainer;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu;
import javax.annotation.Nonnull;
@ -30,7 +30,7 @@ import java.util.Optional;
public class BlockEntityBatteryBank extends BlockEntityMattery {
// 5 на 3
public SimpleSerializableContainer battery_container = new SimpleSerializableContainer(this::setChanged, 5 * 3);
public MatteryContainer battery_container = new MatteryContainer(this::setChanged, 5 * 3);
public static class BatteryBankDistribution {
private final BigDecimal[] distribution;
@ -253,7 +253,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery {
@Override
public void load(CompoundTag nbt) {
if (nbt.contains("battery_bank") && nbt.get("battery_bank") instanceof CompoundTag tag)
battery_container = SimpleSerializableContainer.of(this::setChanged, tag, battery_container.getContainerSize());
battery_container = MatteryContainer.of(this::setChanged, tag, battery_container.getContainerSize());
super.load(nbt);
}

View File

@ -11,6 +11,7 @@ import ru.dbotthepony.mc.otm.MatterGrid;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.BlockMatterCable;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import javax.annotation.Nullable;
@ -30,6 +31,12 @@ public class BlockEntityMatterCable extends BlockEntity implements IMatterGridCe
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
}
@Nullable
@Override
public IPatternStorage getPatternStorage() {
return null;
}
@Override
public void onNeighbourMatterCell(BlockPos pos, Level level, Direction direction, IMatterGridCell cell) {
// OverdriveThatMatters.LOGGER.debug("Try to connect cable entity {} {} to {} {} ({})", this, pos, pos.offset(direction.getNormal()), direction, cell);

View File

@ -17,8 +17,9 @@ import ru.dbotthepony.mc.otm.IMatterGridCell;
import ru.dbotthepony.mc.otm.MatterGrid;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.container.SimpleSerializableContainer;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu;
import javax.annotation.Nonnull;
@ -141,7 +142,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
private final LazyOptional<IMatterHandler> resolver = LazyOptional.of(() -> matter);
public SimpleSerializableContainer matter_container = new SimpleSerializableContainer(this::setChanged, 5 * 3);
public MatteryContainer matter_container = new MatteryContainer(this::setChanged, 5 * 3);
public BlockEntityMatterCapacitorBank(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_CAPACITOR_BANK, p_155229_, p_155230_);
@ -163,7 +164,7 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
@Override
public void load(CompoundTag nbt) {
if (nbt.contains("matter_container") && nbt.get("matter_container") instanceof CompoundTag tag)
matter_container = SimpleSerializableContainer.of(this::setChanged, tag, matter_container.getContainerSize());
matter_container = MatteryContainer.of(this::setChanged, tag, matter_container.getContainerSize());
super.load(nbt);
}
@ -227,6 +228,12 @@ public class BlockEntityMatterCapacitorBank extends BlockEntityMattery implement
return valid ? matter : null;
}
@Nullable
@Override
public IPatternStorage getPatternStorage() {
return null;
}
@Override
public boolean isValidMatterCell() {
return valid;

View File

@ -17,18 +17,15 @@ import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import ru.dbotthepony.mc.otm.*;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.MatterHandlerCapability;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.SimpleSerializableContainer;
import ru.dbotthepony.mc.otm.capability.*;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered implements IItemHandler, IMatterGridCell {
public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredWorker implements IItemHandler, IMatterGridCell {
private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer");
private boolean valid = true;
public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new BigDecimal("20"));
@ -36,7 +33,7 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
private final LazyOptional<IItemHandler> handler_resolver = LazyOptional.of(() -> this);
// вход, выход
public SimpleSerializableContainer item_container = new SimpleSerializableContainer(this::setChanged, 2);
public MatteryContainer item_container = new MatteryContainer(this::setChanged, 2);
public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, p_155230_);
@ -118,7 +115,6 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
@Override
public int getSlotLimit(int slot) {
// return Items.AIR.getMaxStackSize();
return item_container.getMaxStackSize();
}
@ -138,12 +134,15 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
return new MatterDecomposerMenu(containerID, inventory, this);
}
@Nullable
@Override
public IPatternStorage getPatternStorage() {
return null;
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("work_inventory", item_container.serializeNBT());
nbt.putDouble("work_progress", work_progress);
nbt.put("work_item", work_item.serializeNBT());
nbt.put("work_slots", item_container.serializeNBT());
nbt.put("matter_capability", matter.serializeNBT());
return super.save(nbt);
@ -156,13 +155,8 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
if (nbt.contains("matter_capability") && nbt.get("matter_capability") instanceof CompoundTag tag)
matter.deserializeNBT(tag);
if (nbt.contains("work_inventory") && nbt.get("work_inventory") instanceof CompoundTag tag)
item_container = SimpleSerializableContainer.of(this::setChanged, tag, item_container.getContainerSize());
work_progress = nbt.getDouble("work_progress");
if (nbt.contains("work_item") && nbt.get("work_item") instanceof CompoundTag tag)
work_item = ItemStack.of(tag);
if (nbt.contains("work_slots") && nbt.get("work_slots") instanceof CompoundTag tag)
item_container = MatteryContainer.of(this::setChanged, tag, item_container.getContainerSize());
}
@Override
@ -191,51 +185,37 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
return super.getCapability(cap, side);
}
private static final BigDecimal ENERGY_CONSUMPTION_PER_TICK = new BigDecimal("240");
@Nonnull
@Override
protected MachineJobFinish onJobFinish(MachineJob job) {
BigDecimal matter_value = MatterRegistry.getMatterValue(job.stack());
matter.receiveMatterInner(matter_value, false);
return new MachineJobFinish();
}
private double work_progress = 0;
private ItemStack work_item = ItemStack.EMPTY;
@Nullable
@Override
protected MachineJob getNextJob() {
ItemStack stack = item_container.getItem(0);
public double getWorkProgress() {
return work_progress;
if (!stack.isEmpty()) {
ItemStack copy = stack.copy();
copy.setCount(1);
BigDecimal matter_value = MatterRegistry.getMatterValue(copy);
if (!matter_value.equals(BigDecimal.ZERO) && matter.canReceiveAll(matter_value)) {
stack.shrink(1);
return new MachineJob(copy, matter_value.doubleValue() * 35000d);
}
}
return null;
}
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityMatterDecomposer tile) {
tile.tickBatteryCharge();
ItemStack stack = tile.item_container.getItem(0);
if (!stack.isEmpty()) {
BigDecimal matter_value = MatterRegistry.getMatterValue(stack);
if (!matter_value.equals(BigDecimal.ZERO) && tile.matter.canReceiveAll(matter_value)) {
if (!ItemStack.isSameItemSameTags(tile.work_item, stack)) {
tile.work_progress = 0;
tile.work_item = stack.copy();
}
tile.work_progress +=
// work speed multiplier
tile.workSpeedMultiplier(ENERGY_CONSUMPTION_PER_TICK) *
// unit of full work for getting thing done (0.05 MtU is full unit of work, which is equal one real second)
// the more MtUs are in item, the lesser this value should be
(0.05 / matter_value.doubleValue()) *
// the tick time
0.05;
if (tile.work_progress >= 1) {
// work is done!
tile.matter.receiveMatterInner(matter_value, false);
stack.shrink(1);
tile.item_container.setChanged();
tile.work_progress = 0;
}
}
} else if (tile.work_progress != 0) {
tile.work_progress = 0;
tile.work_item = ItemStack.EMPTY;
}
tile.batteryChargeLoop();
tile.workerLoop();
if (tile.matter.getStoredMatter().compareTo(BigDecimal.ZERO) > 0 && tile.grid != null) {
BigDecimal diff = tile.matter.extractMatterInner(tile.matter.getStoredMatter(), true);
@ -286,4 +266,11 @@ public class BlockEntityMatterDecomposer extends BlockEntityMatteryPowered imple
public void setMatterGrid(MatterGrid grid) {
this.grid = grid;
}
private static final BigDecimal BASE_CONSUMPTION = new BigDecimal(240);
@Override
protected BigDecimal getBaseConsumption() {
return BASE_CONSUMPTION;
}
}

View File

@ -0,0 +1,204 @@
package ru.dbotthepony.mc.otm.block.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.IMatterGridCell;
import ru.dbotthepony.mc.otm.MatterGrid;
import ru.dbotthepony.mc.otm.MatterRegistry;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.Collection;
public class BlockEntityMatterScanner extends BlockEntityMatteryPoweredWorker implements IMatterGridCell {
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.matter_scanner");
public MatteryContainer input_slot = new MatteryContainer(this::setChanged, 1);
public BlockEntityMatterScanner(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.MATTER_SCANNER, p_155229_, p_155230_);
energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(40000), new BigDecimal(400), new BigDecimal(400));
}
@Override
public void notifyPatternsChanged() {
is_idling = false;
}
@Override
public void onNeighbourMatterCell(BlockPos pos, Level level, Direction direction, IMatterGridCell cell) {
is_idling = false;
}
@Override
protected Component getDefaultDisplayName() {
return NAME;
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
return new MatterScannerMenu(containerID, inventory, this);
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("work_slots", input_slot.serializeNBT());
return super.save(nbt);
}
@Override
public void load(CompoundTag nbt) {
if (nbt.get("work_slots") instanceof CompoundTag tag)
input_slot = input_slot.of(tag);
super.load(nbt);
}
private static final BigDecimal BASE_CONSUMPTION = new BigDecimal("40");
@Override
@Nonnull
protected BigDecimal getBaseConsumption() {
return BASE_CONSUMPTION;
}
@Nonnull
@Override
protected MachineJobFinish onJobFinish(MachineJob job) {
if (grid == null)
return new MachineJobFinish(false, 100);
ItemStack stack = job.stack();
if (stack.isEmpty() || !MatterRegistry.hasMatterValue(stack))
return new MachineJobFinish();
Collection<IPatternStorage.PatternState> get_state = grid.findPattern(stack.getItem());
IPatternStorage.PatternState find_state = null;
for (IPatternStorage.PatternState state : get_state) {
if (state.item() == stack.getItem() && state.research_percent() < 1d) {
find_state = state;
}
// как бы не так
// может быть это было сделано специально?
//else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
// return null;
//}
}
IPatternStorage.PatternState new_state;
if (find_state != null) {
new_state = new IPatternStorage.PatternState(stack.getItem(), find_state.research_percent() + 0.2d);
} else {
new_state = new IPatternStorage.PatternState(stack.getItem(), 0.2d);
}
if (grid.insertPattern(new_state, false, false)) {
return new MachineJobFinish();
}
return new MachineJobFinish(false, 200);
}
@Nullable
@Override
protected MachineJob getNextJob() {
if (grid == null)
return null;
ItemStack stack = input_slot.getItem(0);
if (stack.isEmpty() || !MatterRegistry.hasMatterValue(stack))
return null;
Collection<IPatternStorage.PatternState> get_state = grid.findPattern(stack.getItem());
IPatternStorage.PatternState find_state = null;
for (IPatternStorage.PatternState state : get_state) {
if (state.item() == stack.getItem() && state.research_percent() < 1d) {
find_state = state;
} else if (state.item() == stack.getItem() && state.research_percent() >= 1d) {
return null;
}
}
IPatternStorage.PatternState new_state;
if (find_state != null) {
new_state = new IPatternStorage.PatternState(stack.getItem(), find_state.research_percent() + 0.2d);
} else {
new_state = new IPatternStorage.PatternState(stack.getItem(), 0.2d);
}
if (grid.insertPattern(new_state, false, true)) {
ItemStack copy = stack.copy();
copy.setCount(1);
stack.shrink(1);
input_slot.setChanged();
return new MachineJob(copy, MatterRegistry.getMatterValue(copy).doubleValue() * 80000d);
}
return null;
}
@Nullable
@Override
public IPatternStorage getPatternStorage() {
return null;
}
private MatterGrid grid;
@Override
public void setLevel(Level p_155231_) {
super.setLevel(p_155231_);
if (grid == null)
scheduleDiscoverNeighbours(getBlockPos(), p_155231_);
}
@Nullable
@Override
public MatterGrid getMatterGrid() {
return grid;
}
@Nullable
@Override
public IMatterHandler getMatterHandler() {
return null;
}
@Override
public boolean isValidMatterCell() {
return !isRemoved();
}
@Override
public void setMatterGrid(MatterGrid grid) {
this.grid = grid;
}
}

View File

@ -13,7 +13,7 @@ import net.minecraftforge.energy.IEnergyStorage;
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.container.SimpleSerializableContainer;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -25,18 +25,9 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
protected final LazyOptional<MatteryMachineEnergyStorage> energy_resolver = LazyOptional.of(() -> energy);;
private boolean valid = true;
public SimpleSerializableContainer battery_container = new SimpleSerializableContainer(this::setChanged, 1);
public MatteryContainer battery_container = new MatteryContainer(this::setChanged, 1);
protected double workSpeedMultiplier(BigDecimal energy_required, boolean simulate) {
BigDecimal extract_much = energy.extractEnergyInner(energy_required, simulate);
return extract_much.divide(energy_required, MatteryCapability.ROUND_RULES).doubleValue();
}
protected double workSpeedMultiplier(BigDecimal energy_required) {
return workSpeedMultiplier(energy_required, false);
}
protected void tickBatteryCharge() {
protected void batteryChargeLoop() {
if (energy == null)
return;
@ -125,7 +116,7 @@ abstract public class BlockEntityMatteryPowered extends BlockEntityMattery {
energy.deserializeNBT(tag);
if (nbt.contains("battery_container") && nbt.get("battery_container") instanceof CompoundTag tag)
battery_container = SimpleSerializableContainer.of(this::setChanged, tag, 1);
battery_container = MatteryContainer.of(this::setChanged, tag, 1);
super.load(nbt);
}

View File

@ -0,0 +1,255 @@
package ru.dbotthepony.mc.otm.block.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
abstract public class BlockEntityMatteryPoweredWorker extends BlockEntityMatteryPowered {
public BlockEntityMatteryPoweredWorker(BlockEntityType<?> p_155228_, BlockPos p_155229_, BlockState p_155230_) {
super(p_155228_, p_155229_, p_155230_);
}
@Nonnull
protected abstract BigDecimal getBaseConsumption();
public record WorkTickContext(MachineJob job, BigDecimal required_power, BigDecimal extracted_power, double work_speed) {
}
public record MachineJobFinish(boolean finished, int throttle) {
public MachineJobFinish() {
this(true, 0);
}
public MachineJobFinish(boolean finished) {
this(finished, 0);
}
}
public record MachineJob(ItemStack stack, double ticks_processing_time, BigDecimal power_consumption_multiplier) {
public MachineJob(ItemStack stack, double ticks_processing_time, BigDecimal power_consumption_multiplier) {
this.stack = stack;
this.ticks_processing_time = ticks_processing_time;
this.power_consumption_multiplier = power_consumption_multiplier;
}
public MachineJob(ItemStack stack, double ticks_processing_time) {
this(stack, ticks_processing_time, BigDecimal.ONE);
}
public CompoundTag serializeNBT() {
CompoundTag store_job = new CompoundTag();
store_job.put("stack", stack.serializeNBT());
store_job.putDouble("ticks_processing_time", ticks_processing_time);
store_job.putString("power_consumption_multiplier", power_consumption_multiplier.toString());
return store_job;
}
@Nullable
public static MachineJob deserializeNBT(@Nullable Tag nbt) {
if (nbt == null)
return null;
if (nbt instanceof CompoundTag tag) {
if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks_processing_time") instanceof DoubleTag ticks_processing_time && tag.get("power_consumption_multiplier") instanceof StringTag power_consumption_multiplier) {
ItemStack stack = ItemStack.of(stack_tag);
if (!stack.isEmpty()) {
return new MachineJob(stack, ticks_processing_time.getAsDouble(), new BigDecimal(power_consumption_multiplier.getAsString()));
}
}
}
return null;
}
}
@Nonnull
protected BigDecimal consumptionPerWork() {
return getBaseConsumption();
}
protected double work_ticks = 0;
protected int throttle_job_finish = 0;
protected MachineJob current_job;
// if is_idling is true, then workerLoop() does nothing
protected boolean is_idling = false;
@Nullable
public MachineJob getCurrentJob() {
return current_job;
}
public boolean cantFinishJob() {
return throttle_job_finish > 0;
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.putDouble("work_ticks", work_ticks);
if (current_job != null) {
nbt.put("current_job", current_job.serializeNBT());
}
return super.save(nbt);
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
if (nbt.get("work_ticks") instanceof DoubleTag tag)
work_ticks = tag.getAsDouble();
current_job = MachineJob.deserializeNBT(nbt.get("current_job"));
if (current_job == null)
work_ticks = 0d;
}
@Override
public void setChanged() {
super.setChanged();
is_idling = false;
}
/**
* @param job current job
* @return whenever machine can finish it's job. return false if machine for whatever reason can't finish it's job,
* waiting on conditions to be met
*/
@Nonnull
abstract protected MachineJobFinish onJobFinish(MachineJob job);
/**
* @param context context for current job
* @return whenever machine can perform it
*/
protected boolean onWorkTick(WorkTickContext context) {
return true;
}
protected void workerLoop() {
if (is_idling) {
return;
}
if (throttle_job_finish > 0) {
throttle_job_finish--;
return;
}
if (current_job == null) {
MachineJob input = getNextJob();
if (input == null) {
is_idling = true;
return;
}
current_job = input;
}
if (current_job.power_consumption_multiplier.compareTo(BigDecimal.ZERO) != 0 && energy.getBatteryLevel().compareTo(BigDecimal.ZERO) == 0)
return;
if (work_ticks < current_job.ticks_processing_time) {
if (current_job.power_consumption_multiplier.compareTo(BigDecimal.ZERO) != 0) {
BigDecimal required_power = consumptionPerWork().multiply(current_job.power_consumption_multiplier);
BigDecimal extracted_power = energy.extractEnergyInner(required_power, true);
double work_speed = extracted_power.divide(required_power, MatteryCapability.ROUND_RULES).doubleValue();
if (!onWorkTick(new WorkTickContext(current_job, required_power, extracted_power, work_speed)))
return;
double new_work_ticks = work_speed + work_ticks;
if (new_work_ticks > current_job.ticks_processing_time) {
work_ticks = current_job.ticks_processing_time;
energy.extractEnergyInner(extracted_power.multiply(new BigDecimal(1d - (new_work_ticks - current_job.ticks_processing_time), MatteryCapability.ROUND_RULES)), false);
} else {
work_ticks = new_work_ticks;
energy.extractEnergyInner(extracted_power, false);
if (work_ticks >= current_job.ticks_processing_time) {
MachineJobFinish status = onJobFinish(current_job);
if (status.finished) {
current_job = null;
work_ticks = 0d;
} else {
throttle_job_finish += status.throttle;
}
}
}
} else {
if (!onWorkTick(new WorkTickContext(current_job, BigDecimal.ZERO, BigDecimal.ZERO, 1d)))
return;
work_ticks += 1d;
if (work_ticks >= current_job.ticks_processing_time) {
MachineJobFinish status = onJobFinish(current_job);
if (status.finished) {
current_job = null;
work_ticks = 0d;
} else {
throttle_job_finish += status.throttle;
}
}
}
} else {
MachineJobFinish status = onJobFinish(current_job);
if (status.finished) {
current_job = null;
work_ticks = 0d;
} else {
throttle_job_finish += status.throttle;
}
}
}
public double getWorkTicks() {
return work_ticks;
}
public double getWorkProgress() {
if (current_job == null)
return 0d;
return Math.min(1d, work_ticks / current_job.ticks_processing_time);
}
/**
* Determine which item can be processed from input slots if idling
* @return any item in input slots. null if no work is available
*/
@Nullable
protected abstract MachineJob getNextJob();
public static <T extends BlockEntity> void basicTicker(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityMatteryPoweredWorker tile) {
tile.batteryChargeLoop();
tile.workerLoop();
}
}
}

View File

@ -0,0 +1,255 @@
package ru.dbotthepony.mc.otm.block.entity;
import com.google.common.collect.ImmutableList;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
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.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import ru.dbotthepony.mc.otm.IMatterGridCell;
import ru.dbotthepony.mc.otm.MatterGrid;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.container.MatteryContainer;
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
public class BlockEntityPatternStorage extends BlockEntityMattery implements IMatterGridCell, IItemHandler, IPatternStorage {
public BlockEntityPatternStorage(BlockPos p_155229_, BlockState p_155230_) {
super(Registry.BlockEntities.PATTERN_STORAGE, p_155229_, p_155230_);
}
public MatteryContainer patterns = new MatteryContainer(this::setChangedPatterns, 3 * 3);
private void setChangedPatterns() {
setChanged();
if (grid != null)
grid.notifyPatternsChanged();
}
private MatterGrid grid;
@Override
public int getSlots() {
return patterns.getContainerSize();
}
@Nonnull
@Override
public ItemStack getStackInSlot(int slot) {
return patterns.getItem(slot);
}
@Nonnull
@Override
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (stack.getCapability(MatteryCapability.PATTERN).resolve().isEmpty())
return stack;
ItemStack self_stack = patterns.getItem(slot);
if (self_stack.isEmpty()) {
if (!simulate) {
patterns.setItem(slot, stack.copy());
}
return ItemStack.EMPTY;
} else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) {
int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount());
int diff = new_count - self_stack.getCount();
if (diff != 0) {
if (!simulate) {
self_stack.grow(diff);
patterns.setChanged();
}
ItemStack copy = stack.copy();
copy.shrink(diff);
return copy;
}
}
return stack;
}
@Nonnull
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (amount <= 0)
return ItemStack.EMPTY;
ItemStack stack = patterns.getItem(slot);
if (stack.isEmpty())
return ItemStack.EMPTY;
if (!stack.isStackable()) {
if (!simulate) {
patterns.setItem(slot, ItemStack.EMPTY);
}
return stack.copy();
}
ItemStack copy = stack.copy();
copy.setCount(Math.min(amount, stack.getCount()));
if (!simulate) {
stack.shrink(copy.getCount());
patterns.setChanged();
}
return copy;
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("patterns", patterns.serializeNBT());
return super.save(nbt);
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
patterns = patterns.of(nbt.get("patterns"));
}
@Override
public int getSlotLimit(int slot) {
return 1;
}
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
return stack.getCapability(MatteryCapability.PATTERN).isPresent();
}
@Override
public void setLevel(Level p_155231_) {
super.setLevel(p_155231_);
if (grid == null)
MatterGrid.scheduleDiscoverNeighbours(this, getBlockPos(), p_155231_);
}
@Nullable
@Override
public MatterGrid getMatterGrid() {
return grid;
}
@Nullable
@Override
public IMatterHandler getMatterHandler() {
return null;
}
@Nullable
@Override
public IPatternStorage getPatternStorage() {
return valid ? this : null;
}
private boolean valid = true;
@Override
public boolean isValidMatterCell() {
return valid;
}
@Override
public void setMatterGrid(MatterGrid grid) {
this.grid = grid;
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
valid = false;
}
@Override
public void reviveCaps() {
super.reviveCaps();
valid = true;
}
private LazyOptional<BlockEntityPatternStorage> resolver = LazyOptional.of(() -> this);
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == MatteryCapability.PATTERN || cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return resolver.cast();
return super.getCapability(cap, side);
}
private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.pattern_storage");
@Override
protected Component getDefaultDisplayName() {
return NAME;
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
return new PatternStorageMenu(containerID, inventory, this);
}
@Override
public Collection<PatternState> getStoredPatterns() {
ArrayList<PatternState> list = new ArrayList<>();
patterns.consumeCapability(MatteryCapability.PATTERN, capability -> list.addAll(capability.getStoredPatterns()));
return ImmutableList.copyOf(list);
}
@Override
public int getCapacity() {
AtomicInteger stored = new AtomicInteger();
patterns.consumeCapability(MatteryCapability.PATTERN, capability -> stored.getAndAdd(capability.getCapacity()));
return stored.get();
}
@Override
public int getStored() {
AtomicInteger stored = new AtomicInteger();
patterns.consumeCapability(MatteryCapability.PATTERN, capability -> stored.getAndAdd(capability.getStored()));
return stored.get();
}
@Override
public boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
for (IPatternStorage storage : patterns.capabilityIterator(MatteryCapability.PATTERN)) {
if (storage.insertPattern(pattern, only_update, simulate)) {
if (!simulate) {
setChangedPatterns();
}
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,63 @@
package ru.dbotthepony.mc.otm.capability;
import net.minecraft.world.item.Item;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public interface IPatternStorage {
record PatternState(Item item, double research_percent) {
public PatternState(@Nonnull Item item, double research_percent) {
this.item = item;
this.research_percent = Math.max(0, Math.min(1, research_percent));
}
public boolean equals(PatternState state) {
return state.item == this.item && state.research_percent == this.research_percent;
}
}
/**
* @return unmodifiable collection of stored patterns
*/
Collection<PatternState> getStoredPatterns();
default Collection<PatternState> findPattern(Item item) {
return findPattern((item2) -> item.equals(item2.item));
}
default Collection<PatternState> findPattern(Predicate<PatternState> predicate) {
return getStoredPatterns().stream().filter(predicate).collect(Collectors.toList());
}
default boolean hasExactPattern(PatternState state) {
for (PatternState state1 : getStoredPatterns()) {
if (state1.equals(state)) {
return true;
}
}
return false;
}
int getCapacity();
int getStored();
/**
* @param pattern pattern to be inserted or update value from
* @param only_update do not insert new pattern if no existing patterns match the pattern
* @param simulate whenever to affect state
* @return whenever operation was successful
*/
boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate);
default boolean insertPattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, false, simulate);
}
default boolean updatePattern(PatternState pattern, boolean simulate) {
return insertPattern(pattern, true, simulate);
}
}

View File

@ -19,11 +19,14 @@ public class MatteryCapability {
@CapabilityInject(IMatterHandler.class)
public static Capability<IMatterHandler> MATTER = null;
@CapabilityInject(IPatternStorage.class)
public static Capability<IPatternStorage> PATTERN = null;
public static void register() {
CapabilityManager.INSTANCE.register(IAndroidCapability.class);
CapabilityManager.INSTANCE.register(IMatteryEnergyStorage.class);
CapabilityManager.INSTANCE.register(IMatterHandler.class);
CapabilityManager.INSTANCE.register(IPatternStorage.class);
}
public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN);

View File

@ -0,0 +1,59 @@
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);
}
}
}

View File

@ -0,0 +1,55 @@
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);
}
}
}

View File

@ -0,0 +1,105 @@
package ru.dbotthepony.mc.otm.container;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.function.Consumer;
public class MatteryContainer extends SimpleContainer {
protected final Runnable watcher;
public MatteryContainer(Runnable watcher, int i) {
super(i);
this.watcher = watcher;
}
public MatteryContainer of(@Nullable CompoundTag tag) {
if (tag == null)
return this;
return MatteryContainer.of(watcher, tag, getContainerSize());
}
public MatteryContainer of(@Nullable Tag tag) {
if (tag == null)
return this;
if (tag instanceof CompoundTag compound)
return MatteryContainer.of(watcher, compound, getContainerSize());
return this;
}
public MatteryContainer(Runnable watcher, ItemStack... p_19152_) {
super(p_19152_);
this.watcher = watcher;
}
public ContainerIteratorItemStack stackIterator() {
return new ContainerIteratorItemStack(this);
}
public void consumeNonEmpty(Consumer<ItemStack> consumer) {
stackIterator().consume(consumer);
}
public <T> ContainerIteratorCapability<T> capabilityIterator(Capability<T> cap) {
return new ContainerIteratorCapability<>(this, cap);
}
public <T> void consumeCapability(Capability<T> cap, Consumer<T> consumer) {
capabilityIterator(cap).consume(consumer);
}
@Override
public void setChanged() {
super.setChanged();
watcher.run();
}
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
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) {
if (tag == null)
return new MatteryContainer(watcher, fallback_size);
MatteryContainer container;
if (tag.contains("size"))
container = new MatteryContainer(watcher, tag.getInt("size"));
else
container = new MatteryContainer(watcher, fallback_size);
if (tag.get("items") instanceof ListTag list)
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;
}
public boolean hasEmptySlot() {
for (int i = 0; i < getContainerSize(); i++) {
if (getItem(i).isEmpty())
return true;
}
return false;
}
}

View File

@ -1,56 +0,0 @@
package ru.dbotthepony.mc.otm.container;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.item.ItemStack;
public class SimpleSerializableContainer extends SimpleContainer {
protected final Runnable watcher;
public SimpleSerializableContainer(Runnable watcher, int i) {
super(i);
this.watcher = watcher;
}
public SimpleSerializableContainer(Runnable watcher, ItemStack... p_19152_) {
super(p_19152_);
this.watcher = watcher;
}
@Override
public void setChanged() {
super.setChanged();
watcher.run();
}
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
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 SimpleSerializableContainer of(Runnable watcher, CompoundTag tag, int fallback_size) {
if (tag == null)
return new SimpleSerializableContainer(watcher, fallback_size);
SimpleSerializableContainer container;
if (tag.contains("size"))
container = new SimpleSerializableContainer(watcher, tag.getInt("size"));
else
container = new SimpleSerializableContainer(watcher, fallback_size);
if (tag.get("items") instanceof ListTag list)
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;
}
}

View File

@ -201,10 +201,9 @@ public class ItemBattery extends Item {
p_41423_.add(INFINITE_STORAGE);
p_41423_.add(THROUGHPUT);
} else {
if (stack.getCapability(MatteryCapability.ENERGY).resolve().get() instanceof BatteryMatteryCapability cap)
p_41423_.add(new TranslatableComponent("otm.item.power.normal.storage", FormattingHelper.formatPower(cap.getBatteryLevel()), FormattingHelper.formatPower(storage)).withStyle(ChatFormatting.GRAY));
else
p_41423_.add(new TranslatableComponent("otm.item.power.normal.storage", "???", FormattingHelper.formatPower(storage)).withStyle(ChatFormatting.GRAY));
stack.getCapability(MatteryCapability.ENERGY).ifPresent(cap ->
p_41423_.add(new TranslatableComponent("otm.item.power.normal.storage", FormattingHelper.formatPower(cap.getBatteryLevel()), FormattingHelper.formatPower(cap.getMaxBatteryLevel())).withStyle(ChatFormatting.GRAY))
);
p_41423_.add(THROUGHPUT);
}

View File

@ -193,10 +193,9 @@ public class ItemMatterCapacitor extends Item {
if (is_creative) {
p_41423_.add(INFINITE_STORAGE);
} else {
if (stack.getCapability(MatteryCapability.MATTER).resolve().get() instanceof ItemMatterCapacitorCapability cap)
p_41423_.add(new TranslatableComponent("otm.item.matter.normal", FormattingHelper.formatMatterValuePlain(cap.getStoredMatter()), FormattingHelper.formatMatterValuePlain(storage)).withStyle(ChatFormatting.GRAY));
else
p_41423_.add(new TranslatableComponent("otm.item.matter.normal", "???", FormattingHelper.formatMatterValuePlain(storage)).withStyle(ChatFormatting.GRAY));
stack.getCapability(MatteryCapability.MATTER).ifPresent(cap ->
p_41423_.add(new TranslatableComponent("otm.item.matter.normal", FormattingHelper.formatMatterValuePlain(cap.getStoredMatter()), FormattingHelper.formatMatterValuePlain(storage)).withStyle(ChatFormatting.GRAY))
);
}
}

View File

@ -0,0 +1,175 @@
package ru.dbotthepony.mc.otm.item;
import com.google.common.collect.ImmutableList;
import net.minecraft.ChatFormatting;
import net.minecraft.core.Direction;
import net.minecraft.nbt.*;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.registries.ForgeRegistry;
import net.minecraftforge.registries.RegistryManager;
import ru.dbotthepony.mc.otm.capability.IPatternStorage;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
public class ItemPatternStorage extends Item {
public final int capacity;
public ItemPatternStorage(int capacity) {
super(new Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1));
this.capacity = capacity;
}
@Nullable
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return new ItemPatternStorageCapability(stack, capacity);
}
@Override
public void appendHoverText(ItemStack p_41421_, @Nullable Level p_41422_, List<Component> list, TooltipFlag p_41424_) {
p_41421_.getCapability(MatteryCapability.PATTERN).ifPresent(capability -> {
list.add(new TranslatableComponent("otm.item.pattern.stored", capability.getStored(), capability.getCapacity()).withStyle(ChatFormatting.GRAY));
for (IPatternStorage.PatternState state : capability.getStoredPatterns()) {
list.add(new TranslatableComponent("otm.item.pattern.line", state.item().getName(new ItemStack(state.item(), 1)), String.format("%.2f", state.research_percent() * 100d)).withStyle(ChatFormatting.AQUA));
}
});
super.appendHoverText(p_41421_, p_41422_, list, p_41424_);
}
public static class ItemPatternStorageCapability implements IPatternStorage, ICapabilityProvider {
private final LazyOptional<IPatternStorage> resolver = LazyOptional.of(() -> this);
public final ItemStack stack;
public final int capacity;
public ItemPatternStorageCapability(ItemStack stack, int capacity) {
this.stack = stack;
this.capacity = capacity;
}
@Override
public int getCapacity() {
return capacity;
}
@Override
public int getStored() {
return getStoredPatterns().size();
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == MatteryCapability.PATTERN)
return resolver.cast();
return LazyOptional.empty();
}
@Override
public Collection<PatternState> getStoredPatterns() {
CompoundTag tag = stack.getOrCreateTag();
if (!tag.contains("otm_patterns") || !(tag.get("otm_patterns") instanceof ListTag))
return Collections.EMPTY_LIST;
ListTag list = tag.getList("otm_patterns", Tag.TAG_COMPOUND);
ArrayList<PatternState> state_list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i);
if (get_tag.get("id") instanceof StringTag id && get_tag.get("progress") instanceof DoubleTag progress) {
Item get_item = RegistryManager.ACTIVE.getRegistry(Item.class).getValue(new ResourceLocation(id.getAsString()));
if (get_item != null)
state_list.add(new PatternState(get_item, progress.getAsDouble()));
}
}
return ImmutableList.copyOf(state_list);
}
@Override
public boolean insertPattern(PatternState pattern, boolean only_update, boolean simulate) {
CompoundTag tag = stack.getOrCreateTag();
ListTag list;
if (tag.get("otm_patterns") instanceof ListTag list1) {
list = list1;
} else {
if (only_update)
return false;
if (simulate)
return capacity > 0;
list = new ListTag();
tag.put("otm_patterns", list);
}
String compare_with = Objects.requireNonNull(pattern.item().getRegistryName()).toString();
int invalid_entries = 0;
for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i);
if (get_tag.get("id") instanceof StringTag id) {
if (compare_with.equals(id.getAsString())) {
if (!simulate) {
get_tag.putDouble("progress", pattern.research_percent());
}
return true;
}
} else {
invalid_entries++;
}
}
if (only_update || capacity <= list.size() - invalid_entries)
return false;
if (invalid_entries > 0) {
if (simulate)
return true;
for (int i = 0; i < list.size(); i++) {
CompoundTag get_tag = list.getCompound(i);
if (!(get_tag.get("id") instanceof StringTag)) {
get_tag.putString("id", compare_with);
get_tag.putDouble("progress", pattern.research_percent());
return true;
}
}
}
if (simulate)
return true;
CompoundTag get_tag = new CompoundTag();
get_tag.putString("id", compare_with);
get_tag.putDouble("progress", pattern.research_percent());
list.add(get_tag);
return true;
}
}
}

View File

@ -3,17 +3,12 @@ package ru.dbotthepony.mc.otm.menu;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.block.entity.BlockEntity;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterCapacitorBank;
import ru.dbotthepony.mc.otm.capability.IMatterHandler;
import ru.dbotthepony.mc.otm.menu.slot.MachineInputSlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot;
import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget;
import javax.annotation.Nullable;
public class MatterCapacitorBankMenu extends MatteryMenu {
public MatterCapacitorBankMenu(int p_38852_, Inventory inventory) {
this(p_38852_, inventory, null);

View File

@ -8,7 +8,7 @@ import ru.dbotthepony.mc.otm.MatterRegistry;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.menu.slot.MachineInputSlot;
import ru.dbotthepony.mc.otm.menu.slot.SlotAutoRenderable;
import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot;
import ru.dbotthepony.mc.otm.menu.widget.MatterLevelWidget;
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
@ -28,7 +28,7 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
Container container = tile != null ? tile.item_container : new SimpleContainer(2);
// Вход
addSlot(new MachineInputSlot(container, 0, 61, 36) {
addSlot(new SlotAutoRenderable(container, 0, 61, 36) {
@Override
public boolean mayPlace(ItemStack p_40231_) {
return MatterRegistry.hasMatterValue(p_40231_);
@ -43,7 +43,7 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
progress_widget = new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36);
} else {
matter_widget = new MatterLevelWidget<>(this, 22, 14, tile.getCapability(MatteryCapability.MATTER).resolve().get());
progress_widget = new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36, () -> (float) tile.getWorkProgress());
progress_widget = new ProgressGaugeWidget<>(this, 61 + 18 + 3, 36, () -> (float) tile.getWorkProgress(), tile::cantFinishJob);
}
addBatterySlot(14);

View File

@ -0,0 +1,50 @@
package ru.dbotthepony.mc.otm.menu;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.MatterRegistry;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner;
import ru.dbotthepony.mc.otm.menu.slot.SlotAutoRenderable;
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
public class MatterScannerMenu extends PoweredMatteryMenu {
public MatterScannerMenu(int p_38852_, Inventory inventory) {
this(p_38852_, inventory, null);
}
public MatterScannerMenu(int p_38852_, Inventory inventory, BlockEntityMatterScanner tile) {
super(Registry.Menus.MATTER_SCANNER, p_38852_, inventory, tile);
Container container = tile != null ? tile.input_slot : new SimpleContainer(1);
addSlot(new SlotAutoRenderable(container, 0, 64, 38) {
@Override
public boolean mayPlace(ItemStack p_40231_) {
return MatterRegistry.hasMatterValue(p_40231_);
}
});
if (tile != null) {
new ProgressGaugeWidget<>(this, 88, 38, () -> (float) tile.getWorkProgress(), tile::cantFinishJob);
} else {
new ProgressGaugeWidget<>(this, 88, 38);
}
addBatterySlot();
addInventorySlots();
}
@Override
protected int getWorkingSlotStart() {
return 0;
}
@Override
protected int getWorkingSlotEnd() {
return 1;
}
}

View File

@ -0,0 +1,40 @@
package ru.dbotthepony.mc.otm.menu;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.block.entity.BlockEntity;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityPatternStorage;
import ru.dbotthepony.mc.otm.menu.slot.PatternSlot;
import javax.annotation.Nullable;
public class PatternStorageMenu extends MatteryMenu {
public PatternStorageMenu(int p_38852_, Inventory inventory) {
this(p_38852_, inventory, null);
}
public PatternStorageMenu(int p_38852_, Inventory inventory, BlockEntityPatternStorage tile) {
super(Registry.Menus.PATTERN_STORAGE, p_38852_, inventory, tile);
Container patterns = tile != null ? tile.patterns : new SimpleContainer(3 * 3);
for (int row = 0; row < 3; row++)
for (int column = 0; column < 3; column++)
addSlot(new PatternSlot(patterns, row * 3 + column, 64 + column * 18, 20 + row * 18));
addInventorySlots();
}
@Override
protected int getWorkingSlotStart() {
return 0;
}
@Override
protected int getWorkingSlotEnd() {
return 3 * 3;
}
}

View File

@ -33,7 +33,7 @@ abstract public class PoweredMatteryMenu extends MatteryMenu {
}
protected void addBatterySlot() {
addBatterySlot(8, 66);
addBatterySlot(10, 66);
}
protected void addBatterySlot(int x) {

View File

@ -0,0 +1,20 @@
package ru.dbotthepony.mc.otm.menu.slot;
import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
public class PatternSlot extends SlotAutoRenderable {
public PatternSlot(Container p_40223_, int index, int x, int y, boolean auto_bg) {
super(p_40223_, index, x, y, auto_bg);
}
public PatternSlot(Container p_40223_, int index, int x, int y) {
super(p_40223_, index, x, y);
}
@Override
public boolean mayPlace(ItemStack p_40231_) {
return p_40231_.getCapability(MatteryCapability.PATTERN).isPresent();
}
}

View File

@ -4,16 +4,15 @@ import net.minecraft.world.Container;
import net.minecraft.world.inventory.Slot;
// Just a sign that this slot needs auto draw
public class MachineInputSlot extends Slot {
public class SlotAutoRenderable extends Slot {
public boolean auto_bg;
public MachineInputSlot(Container p_40223_, int index, int x, int y, boolean auto_bg) {
public SlotAutoRenderable(Container p_40223_, int index, int x, int y, boolean auto_bg) {
super(p_40223_, index, x, y);
this.auto_bg = auto_bg;
}
public MachineInputSlot(Container p_40223_, int index, int x, int y) {
public SlotAutoRenderable(Container p_40223_, int index, int x, int y) {
this(p_40223_, index, x, y, true);
}
}

View File

@ -22,11 +22,15 @@ abstract public class GaugeWidget<T extends MatteryMenu> extends AbstractWidget<
abstract public float getLevel();
@Override
public void renderBackground(MatteryScreen<T> screen, PoseStack pose, int local_x, int local_y, int mouse_x, int mouse_y) {
protected void setupGaugeDrawing() {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, TEXTURE);
}
@Override
public void renderBackground(MatteryScreen<T> screen, PoseStack pose, int local_x, int local_y, int mouse_x, int mouse_y) {
setupGaugeDrawing();
screen.blit(pose, local_x + x, local_y + y, getImageX(), getImageY(), getImageWidth(), getImageHeight());
float level = getLevel();

View File

@ -1,10 +1,12 @@
package ru.dbotthepony.mc.otm.menu.widget;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.ChatFormatting;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.inventory.ContainerData;
import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
@ -13,35 +15,46 @@ import java.util.function.Supplier;
public class ProgressGaugeWidget<T extends MatteryMenu> extends GaugeWidget<T> {
protected final Supplier<Float> progress_supplier;
protected final Supplier<Boolean> is_stuck_supplier;
protected final ContainerData progress_container = new ContainerData() {
private int value;
private int progress;
private int is_stuck;
@Override
public int get(int i) {
return value;
return i == 0 ? progress : is_stuck;
}
@Override
public void set(int i, int i1) {
value = i1;
if (i == 0) {
progress = i1;
} else {
is_stuck = i1;
}
}
@Override
public int getCount() {
return 1;
return 2;
}
};
public ProgressGaugeWidget(T menu, int x, int y, Supplier<Float> progress) {
public ProgressGaugeWidget(T menu, int x, int y, Supplier<Float> progress, Supplier<Boolean> is_stuck_supplier) {
super(menu, x, y);
fill_order = GaugeDirection.LEFT_TO_RIGHT;
addDataSlots(progress_container);
progress_supplier = progress;
this.is_stuck_supplier = is_stuck_supplier;
}
public ProgressGaugeWidget(T menu, int x, int y) {
this(menu, x, y, null);
this(menu, x, y, null, null);
}
public ProgressGaugeWidget(T menu, int x, int y, Supplier<Float> progress) {
this(menu, x, y, progress, null);
}
@Override
@ -68,14 +81,35 @@ public class ProgressGaugeWidget<T extends MatteryMenu> extends GaugeWidget<T> {
public void updateServer() {
if (progress_supplier != null)
progress_container.set(0, (int) (progress_supplier.get() * 10000f));
if (is_stuck_supplier != null)
progress_container.set(1, is_stuck_supplier.get() ? 1 : 0);
}
@Override
protected void setupGaugeDrawing() {
super.setupGaugeDrawing();
if (progress_container.get(1) != 0 && System.currentTimeMillis() % 1500L > 750L) {
RenderSystem.setShaderColor(0.8F, 0.4F, 0.4F, 1.0F);
}
}
@Override
public boolean renderTooltip(MatteryScreen<T> screen, PoseStack pose, int local_x, int local_y, int mouse_x, int mouse_y) {
if (is_hovered) {
List<Component> text = List.of(
new TranslatableComponent("otm.gui.progress_widget", String.format("%.2f", progress_container.get(0) / 100f))
);
List<Component> text;
if (progress_container.get(1) != 0) {
text = List.of(
new TranslatableComponent("otm.gui.progress_widget", String.format("%.2f", progress_container.get(0) / 100f)),
new TranslatableComponent("otm.gui.progress_widget_stuck").withStyle(ChatFormatting.DARK_RED)
);
} else {
text = List.of(
new TranslatableComponent("otm.gui.progress_widget", String.format("%.2f", progress_container.get(0) / 100f))
);
}
screen.renderComponentTooltip(pose, text, mouse_x, mouse_y);

View File

@ -0,0 +1,11 @@
package ru.dbotthepony.mc.otm.screen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.MatterScannerMenu;
public class MatterScannerScreen extends MatteryScreen<MatterScannerMenu> {
public MatterScannerScreen(MatterScannerMenu p_97741_, Inventory p_97742_, Component p_97743_) {
super(p_97741_, p_97742_, p_97743_);
}
}

View File

@ -5,25 +5,17 @@ import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.Slot;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.MatteryCapability;
import ru.dbotthepony.mc.otm.menu.FormattingHelper;
import ru.dbotthepony.mc.otm.menu.MatteryMenu;
import ru.dbotthepony.mc.otm.menu.slot.BatterySlot;
import ru.dbotthepony.mc.otm.menu.slot.MachineInputSlot;
import ru.dbotthepony.mc.otm.menu.slot.SlotAutoRenderable;
import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot;
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot;
import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget;
import java.math.BigDecimal;
import java.util.List;
import java.util.function.Supplier;
public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScreen<T> {
protected static final ResourceLocation CONTAINER_BASE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/generic_machine.png");
public static final ResourceLocation WIDGETS = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets.png");
@ -106,7 +98,7 @@ public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScree
} else {
renderRegularSlot(pose, slot1.x, slot1.y);
}
} else if (slot instanceof MachineInputSlot slot1 && slot1.auto_bg) {
} else if (slot instanceof SlotAutoRenderable slot1 && slot1.auto_bg) {
renderRegularSlot(pose, slot1.x, slot1.y);
} else if (slot instanceof MatterContainerInputSlot slot1 && slot1.auto_bg) {
renderRegularSlot(pose, slot1.x, slot1.y);

View File

@ -0,0 +1,11 @@
package ru.dbotthepony.mc.otm.screen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.PatternStorageMenu;
public class PatternStorageScreen extends MatteryScreen<PatternStorageMenu> {
public PatternStorageScreen(PatternStorageMenu p_97741_, Inventory p_97742_, Component p_97743_) {
super(p_97741_, p_97742_, p_97743_);
}
}

View File

@ -7,6 +7,7 @@
"otm.gui.power.name": "MtE",
"otm.gui.progress_widget": "Progress: %s%%",
"otm.gui.progress_widget_stuck": "The machine can't finish it's work, check configuration",
"otm.gui.matter.percentage_level": "Matter level: %s%%",
"otm.gui.matter.format": "Matter: %s",
@ -18,6 +19,9 @@
"otm.item.power.normal.storage": "Stored energy: %s / %s",
"otm.item.power.normal.throughput": "Max I/O %s / %s",
"otm.item.pattern.stored": "Stored patterns: %s / %s",
"otm.item.pattern.line": "%s [%s%%]",
"otm.item.matter.infinite": "Stored matter: Infinity / Infinity",
"otm.item.matter.normal": "Stored matter: %s / %s",
@ -48,6 +52,8 @@
"block.overdrive_that_matters.matter_decomposer": "Matter decomposer",
"block.overdrive_that_matters.matter_capacitor_bank": "Matter capacitor bank",
"block.overdrive_that_matters.matter_cable": "Matter network cable",
"block.overdrive_that_matters.pattern_storage": "Pattern storage",
"block.overdrive_that_matters.matter_scanner": "Matter scanner",
"item.overdrive_that_matters.pill_android": "Android pill",
"item.overdrive_that_matters.pill_humane": "Humane pill",
@ -60,5 +66,7 @@
"item.overdrive_that_matters.battery_creative": "Creative Battery",
"item.overdrive_that_matters.matter_capacitor_normal": "Matter capacitor",
"item.overdrive_that_matters.matter_capacitor_creative": "Creative matter capacitor"
"item.overdrive_that_matters.matter_capacitor_creative": "Creative matter capacitor",
"item.overdrive_that_matters.pattern_drive_normal": "Pattern drive"
}