Skip to content

Commit

Permalink
Rewrite and overhaul bulk compression system (#69)
Browse files Browse the repository at this point in the history
- Rework the way chains are generated and represented in terms of overall multiplier of a base unit item
- Add support for overriding reversibility checks for recipes to allow items such as nether quartz and magma cream to be compressed
  • Loading branch information
62832 authored Aug 28, 2023
1 parent ae87e6b commit ceadc53
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.IntrinsicHolderTagsProvider;
import net.minecraft.data.tags.ItemTagsProvider;
import net.minecraft.tags.BlockTags;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block;

import appeng.api.features.P2PTunnelAttunement;
Expand All @@ -18,8 +19,8 @@
import gripe._90.megacells.definition.MEGATags;

public class CommonTagProvider {
public static class Items extends ItemTagsProvider {
public Items(
public static class ItemTags extends ItemTagsProvider {
public ItemTags(
PackOutput output,
CompletableFuture<HolderLookup.Provider> registries,
CompletableFuture<TagLookup<Block>> blockTags) {
Expand All @@ -36,11 +37,20 @@ protected void addTags(HolderLookup.Provider provider) {
tag(MEGATags.MEGA_PATTERN_PROVIDER)
.add(MEGABlocks.MEGA_PATTERN_PROVIDER.asItem())
.add(MEGAItems.MEGA_PATTERN_PROVIDER.asItem());

tag(MEGATags.COMPRESSION_OVERRIDES)
.add(Items.QUARTZ)
.add(Items.AMETHYST_SHARD)
.add(Items.GLOWSTONE_DUST)
.add(Items.CLAY_BALL)
.add(Items.MELON_SLICE)
.add(Items.MAGMA_CREAM)
.addOptionalTag(new ResourceLocation("functionalstorage", "ignore_crafting_check"));
}
}

public static class Blocks extends IntrinsicHolderTagsProvider<Block> {
public Blocks(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> registries) {
public static class BlockTags extends IntrinsicHolderTagsProvider<Block> {
public BlockTags(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> registries) {
super(packOutput, Registries.BLOCK, registries, block -> BuiltInRegistries.BLOCK
.getResourceKey(block)
.orElseThrow());
Expand All @@ -49,7 +59,7 @@ public Blocks(PackOutput packOutput, CompletableFuture<HolderLookup.Provider> re
@Override
protected void addTags(HolderLookup.Provider provider) {
for (var block : MEGABlocks.getBlocks()) {
tag(BlockTags.MINEABLE_WITH_PICKAXE).add(block.block());
tag(net.minecraft.tags.BlockTags.MINEABLE_WITH_PICKAXE).add(block.block());
}

tag(MEGATags.SKY_STEEL_BLOCK).add(MEGABlocks.SKY_STEEL_BLOCK.block());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ public final class MEGATags {

public static final TagKey<Item> MEGA_PATTERN_PROVIDER =
TagKey.create(Registries.ITEM, MEGACells.makeId("mega_pattern_provider"));

public static final TagKey<Item> COMPRESSION_OVERRIDES =
TagKey.create(Registries.ITEM, MEGACells.makeId("compression_overrides"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
import static gripe._90.megacells.definition.MEGAItems.COMPRESSION_CARD;

import java.math.BigInteger;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;

import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
Expand All @@ -24,7 +20,6 @@
import appeng.api.storage.cells.CellState;
import appeng.api.storage.cells.ISaveProvider;
import appeng.api.storage.cells.StorageCell;
import appeng.util.prioritylist.IPartitionList;

import gripe._90.megacells.item.MEGABulkCell;
import gripe._90.megacells.service.CompressionService;
Expand All @@ -38,10 +33,8 @@ public class BulkCellInventory implements StorageCell {

private AEItemKey storedItem;
private final AEItemKey filterItem;
private final IPartitionList partitionList;

private final Object2IntMap<AEItemKey> compressed;
private final Object2IntMap<AEItemKey> decompressed;
private final Object2LongMap<AEItemKey> compressionChain;
private BigInteger unitCount;
private AEItemKey highestCompressed;
private final long unitFactor;
Expand All @@ -53,16 +46,9 @@ public BulkCellInventory(MEGABulkCell cell, ItemStack o, ISaveProvider container
this.i = o;
this.container = container;

var config = cell.getConfigInventory(i);
this.filterItem = (AEItemKey) config.getKey(0);

var builder = IPartitionList.builder();
builder.addAll(config.keySet());
this.partitionList = builder.build();

this.compressed = CompressionService.getVariants(filterItem, false);
this.decompressed = CompressionService.getVariants(filterItem, true);
this.unitFactor = decompressed.values().intStream().asLongStream().reduce(1, Math::multiplyExact);
this.filterItem = (AEItemKey) cell.getConfigInventory(i).getKey(0);
this.compressionChain = CompressionService.getChain(filterItem).orElseGet(Object2LongLinkedOpenHashMap::new);
this.unitFactor = compressionChain.containsKey(filterItem) ? compressionChain.getLong(filterItem) : 1;

this.storedItem = getTag().contains(KEY) ? AEItemKey.fromTag(getTag().getCompound(KEY)) : null;
this.unitCount = !getTag().getString(UNIT_COUNT).isEmpty()
Expand Down Expand Up @@ -125,23 +111,22 @@ public long insert(AEKey what, long amount, Actionable mode, IActionSource sourc
return 0;
}

if (!compressionEnabled && (!partitionList.isListed(what) || storedItem != null && !storedItem.equals(what))) {
if (!compressionEnabled && (!filterItem.equals(what) || storedItem != null && !storedItem.equals(what))) {
return 0;
}

if (compressionEnabled
&& !partitionList.isListed(what)
&& !compressed.containsKey(item)
&& !decompressed.containsKey(item)) {
if (compressionEnabled && !filterItem.equals(what) && !compressionChain.containsKey(what)) {
return 0;
}

var units = BigInteger.valueOf(amount).multiply(compressedTransferFactor(item));
var factor = BigInteger.valueOf(compressionChain.containsKey(item) ? compressionChain.getLong(item) : 1);
var units = BigInteger.valueOf(amount).multiply(factor);

if (mode == Actionable.MODULATE) {
if (storedItem == null) {
storedItem = filterItem;
}

unitCount = unitCount.add(units);
saveChanges();
}
Expand All @@ -156,20 +141,20 @@ public long extract(AEKey what, long amount, Actionable mode, IActionSource sour
}

var itemCount = unitCount.divide(BigInteger.valueOf(unitFactor));

if (!compressionEnabled && (itemCount.signum() < 1 || !storedItem.equals(what))) {
return 0;
}

if (compressionEnabled
&& !storedItem.equals(what)
&& !filterItem.equals(what)
&& !compressed.containsKey(item)
&& !decompressed.containsKey(item)) {
&& !compressionChain.containsKey(item)) {
return 0;
}

var extractionFactor = compressedTransferFactor(item);
var units = BigInteger.valueOf(amount).multiply(extractionFactor);
var factor = BigInteger.valueOf(compressionChain.containsKey(item) ? compressionChain.getLong(item) : 1);
var units = BigInteger.valueOf(amount).multiply(factor);
var currentUnitCount = unitCount;

if (currentUnitCount.compareTo(units) <= 0) {
Expand All @@ -178,41 +163,18 @@ public long extract(AEKey what, long amount, Actionable mode, IActionSource sour
unitCount = BigInteger.ZERO;
saveChanges();
}
return clampedLong(currentUnitCount.divide(extractionFactor), Long.MAX_VALUE);

return clampedLong(currentUnitCount.divide(factor), Long.MAX_VALUE);
} else {
if (mode == Actionable.MODULATE) {
unitCount = unitCount.subtract(units);
saveChanges();
}
return clampedLong(units.divide(extractionFactor), Long.MAX_VALUE);
}
}

private BigInteger compressedTransferFactor(AEItemKey what) {
if (compressed.getInt(what) > 0) {
return compressedTransferFactor(compressed, unitFactor, keys -> Pair.of(0, keys.indexOf(what) + 1));
} else if (decompressed.getInt(what) > 0) {
return compressedTransferFactor(decompressed, 1, keys -> Pair.of(keys.indexOf(what) + 1, keys.size()));
} else {
return BigInteger.valueOf(unitFactor);
return clampedLong(units.divide(factor), Long.MAX_VALUE);
}
}

private BigInteger compressedTransferFactor(
Object2IntMap<AEItemKey> variants, long baseFactor, Function<List<?>, Pair<Integer, Integer>> subLister) {
var variantKeys = new LinkedList<>(variants.keySet());
var toStored = new Object2IntLinkedOpenHashMap<>(variants);

var range = subLister.apply(variantKeys);
toStored.keySet().retainAll(variantKeys.subList(range.first(), range.second()));

for (var i : toStored.values()) {
baseFactor *= i;
}

return BigInteger.valueOf(baseFactor);
}

private void saveChanges() {
isPersisted = false;

Expand Down Expand Up @@ -246,37 +208,29 @@ public void getAvailableStacks(KeyCounter out) {
if (storedItem != null) {
var stackLimit = (long) Math.pow(2, 42);

if (compressionEnabled && storedItem.equals(filterItem)) {
var allVariants = new Object2IntLinkedOpenHashMap<AEItemKey>();

if (!decompressed.isEmpty()) {
var decompressedKeys = new LinkedList<>(decompressed.keySet());
Collections.reverse(decompressedKeys);
decompressedKeys.forEach(k -> allVariants.put(k, decompressed.getInt(k)));

allVariants.put(storedItem, decompressed.getInt(decompressedKeys.getLast()));
allVariants.putAll(compressed);
} else if (!compressed.isEmpty()) {
allVariants.put(
storedItem,
compressed.values().intStream().findFirst().orElseThrow());
allVariants.putAll(compressed);
} else {
allVariants.put(storedItem, 1);
}

if (compressionEnabled && storedItem.equals(filterItem) && !compressionChain.isEmpty()) {
var count = unitCount;
var variants = new ObjectArrayList<>(compressionChain.keySet());

for (var variant : allVariants.keySet()) {
var compressionFactor = BigInteger.valueOf(allVariants.getInt(variant));
for (var i = 0; i < variants.size(); i++) {
var variant = variants.get(i);

if (count.divide(compressionFactor).signum() == 1 && variant != allVariants.lastKey()) {
out.add(variant, clampedLong(count.remainder(compressionFactor), stackLimit));
count = count.divide(compressionFactor);
} else {
if (i == variants.size() - 1) {
out.add(variant, clampedLong(count, stackLimit));
highestCompressed = variant;
break;
} else {
var nextVariant = variants.get(i + 1);
var compressionFactor = BigInteger.valueOf(
compressionChain.getLong(nextVariant) / compressionChain.getLong(variant));

if (count.divide(compressionFactor).signum() == 1) {
out.add(variant, count.remainder(compressionFactor).longValue());
count = count.divide(compressionFactor);
} else {
out.add(variant, clampedLong(count, stackLimit));
highestCompressed = variant;
break;
}
}
}
} else {
Expand All @@ -287,8 +241,7 @@ public void getAvailableStacks(KeyCounter out) {

@Override
public boolean isPreferredStorageFor(AEKey what, IActionSource source) {
return what instanceof AEItemKey item
&& (partitionList.isListed(item) || compressed.containsKey(item) || decompressed.containsKey(item));
return what instanceof AEItemKey item && (filterItem.equals(item) || compressionChain.containsKey(item));
}

@Override
Expand Down
Loading

0 comments on commit ceadc53

Please sign in to comment.