Skip to content

Commit

Permalink
Add InventoryOverview
Browse files Browse the repository at this point in the history
  • Loading branch information
FirstMegaGame4 committed Aug 17, 2023
1 parent 7401ea3 commit 123e51e
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.mmodding.mmodding_lib.library.glint.GlintPackView;
import com.mmodding.mmodding_lib.library.client.utils.MModdingClientGlobalMaps;
import com.mmodding.mmodding_lib.library.items.settings.AdvancedItemSettings;
import com.mmodding.mmodding_lib.library.items.tooltipdata.InventoryTooltipData;
import com.mmodding.mmodding_lib.library.items.tooltip.data.InventoryTooltipData;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.client.item.TooltipContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.mmodding.mmodding_lib.library.client.tooltip;

import com.mmodding.mmodding_lib.library.items.tooltipdata.InventoryTooltipData;
import com.mmodding.mmodding_lib.library.items.tooltip.data.InventoryTooltipData;
import net.minecraft.client.gui.tooltip.BundleTooltipComponent;
import org.quiltmc.loader.api.minecraft.ClientOnly;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import com.mmodding.mmodding_lib.MModdingLib;
import com.mmodding.mmodding_lib.library.containers.AdvancedInventory;
import com.mmodding.mmodding_lib.library.containers.DefaultContainer;
import com.mmodding.mmodding_lib.library.items.tooltipdata.InventoryTooltipData;
import com.mmodding.mmodding_lib.library.items.tooltip.InventoryOverview;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.client.item.TooltipData;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
Expand All @@ -17,20 +16,17 @@
import net.minecraft.screen.*;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World;
import org.apache.commons.lang3.function.TriFunction;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.concurrent.atomic.AtomicBoolean;

public abstract class CustomItemWithInventory extends Item implements ItemRegistrable, NamedScreenHandlerFactory {
public abstract class CustomItemWithInventory extends Item implements NamedScreenHandlerFactory, InventoryOverview, ItemRegistrable {

private final AtomicBoolean registered = new AtomicBoolean(false);

Expand Down Expand Up @@ -64,18 +60,6 @@ public boolean canBeNested() {
return false;
}

@Nullable
public DefaultedList<ItemStack> getContent(ItemStack stack) {
if (stack.getNbt() != null) {
if (stack.getNbt().contains("Items", NbtElement.LIST_TYPE)) {
DefaultedList<ItemStack> content = DefaultedList.ofSize(this.inventory.size(), ItemStack.EMPTY);
Inventories.readNbt(stack.getNbt(), content);
return content;
}
}
return null;
}

@Override
public Optional<TooltipData> getTooltipData(ItemStack stack) {
if (this.getContent(stack) != null) {
Expand All @@ -86,66 +70,13 @@ public Optional<TooltipData> getTooltipData(ItemStack stack) {
}
}

public Optional<TooltipData> appendTooltipSlots(DefaultedList<ItemStack> content) {
if (this.getTooltipMode().isSlotsOverview()) {
if (this.getTooltipMode().equals(TooltipMode.ALL_SLOTS_OVERVIEW)) {
if (this.getOptionalRows().isPresent() && this.getOptionalColumns().isPresent()) {
return Optional.of(new InventoryTooltipData(this.inventory, content, this.getOptionalRows().getAsInt(), this.getOptionalColumns().getAsInt()));
}
else if (this.defaultContainer != DefaultContainer.NULL) {
int rows = switch (this.defaultContainer) {
case DEFAULT_9X1 -> 1;
case DEFAULT_9X2 -> 2;
case DEFAULT_9X4 -> 4;
case DEFAULT_9X5 -> 5;
case DEFAULT_9X6 -> 6;
default -> 3;
};
int columns = !this.defaultContainer.equals(DefaultContainer.DEFAULT_3X3) ? 9 : 3;
return Optional.of(new InventoryTooltipData(this.inventory, content, rows, columns));
}
else {
return Optional.of(new InventoryTooltipData(this.inventory, content, false, false));
}
}
else if (this.getTooltipMode().equals(TooltipMode.FILLED_SLOTS_OVERVIEW)) {
return Optional.of(new InventoryTooltipData(this.inventory, content, true, false));
}
else if (this.getTooltipMode().equals(TooltipMode.GROUPED_SLOTS_OVERVIEW)) {
return Optional.of(new InventoryTooltipData(this.inventory, content, true, true));
}
}
return Optional.empty();
}

@Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context) {
if (this.getContent(stack) != null) {
this.appendTooltipLines(this.getContent(stack), world, tooltip, context);
}
}

public void appendTooltipLines(DefaultedList<ItemStack> content, @Nullable World world, List<Text> tooltip, TooltipContext context) {
if (this.getTooltipMode().isLines()) {
int total = 0;
int displayed = 0;

for (ItemStack stack : content) {
if (!stack.isEmpty()) {
total++;
if (this.getTooltipMode().equals(TooltipMode.UNLIMITED_LINES) || displayed <= 4) {
displayed++;
tooltip.add(stack.getName().copy().append(" x").append(String.valueOf(stack.getCount())));
}
}
}

if (this.getTooltipMode().equals(TooltipMode.LIMITED_LINES) && total - displayed > 0) {
tooltip.add(Text.translatable("container.shulkerBox.more", total - displayed).formatted(Formatting.ITALIC));
}
}
}

@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
this.hand = hand;
Expand Down Expand Up @@ -196,16 +127,14 @@ public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, Pla
};
}

public TooltipMode getTooltipMode() {
return TooltipMode.LIMITED_LINES;
}

public OptionalInt getOptionalRows() {
return OptionalInt.empty();
@Override
public Inventory getInventory() {
return this.inventory;
}

public OptionalInt getOptionalColumns() {
return OptionalInt.empty();
@Override
public DefaultContainer getDefaultContainer() {
return this.defaultContainer;
}

@Nullable
Expand All @@ -231,58 +160,4 @@ public boolean isNotRegistered() {
public void setRegistered() {
this.registered.set(true);
}

public enum TooltipMode {

/**
* The item does not render any specific tooltips.
*/
WITHOUT_ANY,

/**
* The item renders its tooltip in a series of lines indicating its inventory content.
* <br>Number of lines are limited just like shulkers.
* @apiNote Default value of {@link CustomItemWithInventory#getTooltipMode()}
*/
LIMITED_LINES,

/**
* The item renders its tooltip in a series of lines indicating its inventory content.
* <br>Number of lines are unlimited.
*/
UNLIMITED_LINES,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>Slots are rendered for each type of item regardless of their number just like bundles.
* <br>Overview does not follow inventory shape.
*/
GROUPED_SLOTS_OVERVIEW,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>Only filled slots are rendered.
* <br>Overview does not follow inventory shape.
*/
FILLED_SLOTS_OVERVIEW,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>All slots are rendered even if there are empty.
* <br>Overview will follow inventory shape when using {@link DefaultContainer}, otherwise it will not.
*/
ALL_SLOTS_OVERVIEW;

public boolean isNothing() {
return this.equals(WITHOUT_ANY);
}

public boolean isLines() {
return this.equals(LIMITED_LINES) || this.equals(UNLIMITED_LINES);
}

public boolean isSlotsOverview() {
return this.equals(GROUPED_SLOTS_OVERVIEW) || this.equals(FILLED_SLOTS_OVERVIEW) || this.equals(ALL_SLOTS_OVERVIEW);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package com.mmodding.mmodding_lib.library.items.tooltip;

import com.mmodding.mmodding_lib.library.containers.DefaultContainer;
import com.mmodding.mmodding_lib.library.items.tooltip.data.InventoryTooltipData;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.client.item.TooltipData;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtElement;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

public interface InventoryOverview {

Inventory getInventory();

default DefaultContainer getDefaultContainer() {
return DefaultContainer.NULL;
}

@Nullable
default DefaultedList<ItemStack> getContent(ItemStack stack) {
if (stack.getNbt() != null) {
if (stack.getNbt().contains("Items", NbtElement.LIST_TYPE)) {
DefaultedList<ItemStack> content = DefaultedList.ofSize(this.getInventory().size(), ItemStack.EMPTY);
Inventories.readNbt(stack.getNbt(), content);
return content;
}
}
return null;
}

default Optional<TooltipData> appendTooltipSlots(DefaultedList<ItemStack> content) {
if (this.getTooltipMode().isSlotsOverview()) {
if (this.getTooltipMode().equals(TooltipMode.ALL_SLOTS_OVERVIEW)) {
if (this.getOptionalColumns().isPresent() && this.getOptionalRows().isPresent()) {
return Optional.of(new InventoryTooltipData(this.getInventory(), content, this.getOptionalColumns().getAsInt(), this.getOptionalRows().getAsInt()));
}
else if (this.getDefaultContainer() != DefaultContainer.NULL) {
int rows = switch (this.getDefaultContainer()) {
case DEFAULT_9X1 -> 1;
case DEFAULT_9X2 -> 2;
case DEFAULT_9X4 -> 4;
case DEFAULT_9X5 -> 5;
case DEFAULT_9X6 -> 6;
default -> 3;
};
int columns = !this.getDefaultContainer().equals(DefaultContainer.DEFAULT_3X3) ? 9 : 3;
return Optional.of(new InventoryTooltipData(this.getInventory(), content, rows, columns));
}
else {
return Optional.of(new InventoryTooltipData(this.getInventory(), content, false, false));
}
}
else if (this.getTooltipMode().equals(TooltipMode.FILLED_SLOTS_OVERVIEW)) {
return Optional.of(new InventoryTooltipData(this.getInventory(), content, true, false));
}
else if (this.getTooltipMode().equals(TooltipMode.GROUPED_SLOTS_OVERVIEW)) {
return Optional.of(new InventoryTooltipData(this.getInventory(), content, true, true));
}
}
return Optional.empty();
}

default void appendTooltipLines(DefaultedList<ItemStack> content, @Nullable World world, List<Text> tooltip, TooltipContext context) {
if (this.getTooltipMode().isLines()) {
int total = 0;
int displayed = 0;

for (ItemStack stack : content) {
if (!stack.isEmpty()) {
total++;
if (this.getTooltipMode().equals(TooltipMode.UNLIMITED_LINES) || displayed <= 4) {
displayed++;
tooltip.add(stack.getName().copy().append(" x").append(String.valueOf(stack.getCount())));
}
}
}

if (this.getTooltipMode().equals(TooltipMode.LIMITED_LINES) && total - displayed > 0) {
tooltip.add(Text.translatable("container.shulkerBox.more", total - displayed).formatted(Formatting.ITALIC));
}
}
}

default TooltipMode getTooltipMode() {
return TooltipMode.LIMITED_LINES;
}

default OptionalInt getOptionalColumns() {
return OptionalInt.empty();
}

default OptionalInt getOptionalRows() {
return OptionalInt.empty();
}

enum TooltipMode {

/**
* The item does not render any specific tooltips.
*/
WITHOUT_ANY,

/**
* The item renders its tooltip in a series of lines indicating its inventory content.
* <br>Number of lines are limited just like shulkers.
* @apiNote Default value of {@link InventoryOverview#getTooltipMode()}
*/
LIMITED_LINES,

/**
* The item renders its tooltip in a series of lines indicating its inventory content.
* <br>Number of lines are unlimited.
*/
UNLIMITED_LINES,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>Slots are rendered for each type of item regardless of their number just like bundles.
* <br>Overview does not follow inventory shape.
*/
GROUPED_SLOTS_OVERVIEW,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>Only filled slots are rendered.
* <br>Overview does not follow inventory shape.
*/
FILLED_SLOTS_OVERVIEW,

/**
* The item renders its tooltip in a series of slots indicating its inventory content.
* <br>All slots are rendered even if there are empty.
* <br>Overview will follow an inventory shape when using {@link InventoryOverview#getOptionalColumns()}
* and {@link InventoryOverview#getOptionalRows()} or {@link DefaultContainer}, otherwise it will not.
*/
ALL_SLOTS_OVERVIEW;

public boolean isNothing() {
return this.equals(WITHOUT_ANY);
}

public boolean isLines() {
return this.equals(LIMITED_LINES) || this.equals(UNLIMITED_LINES);
}

public boolean isSlotsOverview() {
return this.equals(GROUPED_SLOTS_OVERVIEW) || this.equals(FILLED_SLOTS_OVERVIEW) || this.equals(ALL_SLOTS_OVERVIEW);
}
}
}
Loading

0 comments on commit 123e51e

Please sign in to comment.