Dank Storage

Dank Storage

30M Downloads

1.19.2 dankless dock drain

kreezxil opened this issue · 6 comments

commented

Discovered a repeatable issue with the dock, and may or may not have anything to-do item pipez from the Pipez mod.

When removing the dank from a dock, the dock will sometimes get confused and think there is a dank of the same frequency in it. This allows you to drain your active dank in the field without having to worry about the dock having a dank of the same frequency within itself.

commented

Weird, I'll try to reproduce, but an empty dock shouldn't have a frequency.

commented

Could you run /data get on the dock when it is empty?

commented
commented

Sorry, that was a long moment, had to run my mom to the ER. She's ok now. It wasn't major, but it certainly seemed major at the time.

image

https://www.youtube.com/watch?v=N0JX6Wk8HQs

commented

I have a dank dock with this issue:
image

commented

When right clicking the dock, this is called

if (held.getItem() instanceof DankItem) {
if (state.getValue(TIER) > 0) {
dockBlockEntity.giveToPlayer(player);
}
dockBlockEntity.addDank(held);
return InteractionResult.SUCCESS;
}
if (player.isShiftKeyDown() && state.getValue(TIER) > 0) {
dockBlockEntity.giveToPlayer(player);
return InteractionResult.SUCCESS;
}

which calls

public void giveToPlayer(Player player) {
ItemStack dankInStack = removeDankWithoutItemSpawn();
if (!player.addItem(dankInStack)) {
ItemEntity entity = new ItemEntity(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), dankInStack);
level.addFreshEntity(entity);
}
}
public void removeDankWithItemSpawn() {
ItemStack dankInStack = removeDankWithoutItemSpawn();
ItemEntity entity = new ItemEntity(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), dankInStack);
level.addFreshEntity(entity);
}
public ItemStack removeDankWithoutItemSpawn() {
int tier = getBlockState().getValue(DockBlock.TIER);
if (tier == 0) {
throw new RuntimeException("tried to remove a null dank?");
}
level.setBlockAndUpdate(worldPosition, getBlockState().setValue(DockBlock.TIER, 0));
ItemStack stack = new ItemStack(Utils.getItemFromTier(tier));
if (settings != null) {
stack.getOrCreateTag().put(Utils.SET, settings);
}
settings = null;
if (hasCustomName() && originalName) {
stack.setHoverName(getCustomName());
}
setCustomName(null);
originalName = false;
setChanged();
return stack;
}
public void addDank(ItemStack tank) {
if (tank.getItem() instanceof DankItem) {
DankStats stats = ((DankItem) tank.getItem()).stats;
level.setBlockAndUpdate(worldPosition, getBlockState().setValue(DockBlock.TIER, stats.ordinal()));
originalName = tank.hasCustomHoverName();
if (originalName) {
setCustomName(tank.getHoverName());
}
CompoundTag iSettings = Utils.getSettings(tank);
tank.shrink(1);
DankInventory dankInventory;
if (iSettings != null && iSettings.contains(Utils.ID)) {
this.settings = iSettings;
dankInventory = DankStorage.instance.data.getInventory(iSettings.getInt(Utils.ID));
} else {
this.settings = new CompoundTag();
int newId = DankStorage.instance.data.getNextID();
dankInventory = DankStorage.instance.data.getOrCreateInventory(newId, stats);
settings.putInt(Utils.ID, newId);
}
if (stats != dankInventory.dankStats) {
dankInventory.upgradeTo(stats);
}
setChanged();
}
}

and the get caps is

public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
return cap == ForgeCapabilities.ITEM_HANDLER ? LazyOptional.of(this::getInventory).cast() : super.getCapability(cap, side);
}

which calls

public DankInventory getInventory() {
if (settings != null && settings.contains(Utils.ID)) {
int id = settings.getInt(Utils.ID);
DankInventory dankInventory = DankStorage.instance.data.getInventory(id);
//if the id is too high
if (dankInventory == null) {
int next = DankStorage.instance.data.getNextID();
dankInventory = DankStorage.instance.data
.getOrCreateInventory(next, DankStats.values()[getBlockState().getValue(DockBlock.TIER)]);
settings.putInt(Utils.ID, next);
}
return dankInventory;
}
return DUMMY;
}

so if you ask for IItemHandler capability with a dank in it, you get a reference to the DankInventory object, but when the contents changes the pipe mod still has a reference to the DankInventory since invalidateCaps is not being called by dank when the inventory changes.

This is similar to this issue

JDKDigital/productivemetalworks#28

Adding a call to invalidateCaps in removeDankWithoutItemSpawn will fix it I think since that method is called when adding and removing a dank from the dock

if (state.getValue(TIER) > 0) {
dockBlockEntity.giveToPlayer(player);
}
dockBlockEntity.addDank(held);