Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {

// Project properties
group = "alecsio.modularmachineryaddons"
version = "2.0.3"
version = "2.0.4"

// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod
java {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
+ "after:mekanism@[1.12.2-9.8.3.390,);"
,
acceptedMinecraftVersions = "[1.12]",
acceptableRemoteVersions = "[2.0.3]"
acceptableRemoteVersions = "[2.0.4]"
)
public class ModularMachineryAddons {

public static final String MODID = "modularmachineryaddons";
public static final String NAME = "Modular Machinery: Community Edition Addons";
public static final String VERSION = "2.0.3";
public static final String VERSION = "2.0.4";
public static final String CLIENT_PROXY = "github.alecsio.mmceaddons.client.ClientProxy";
public static final String COMMON_PROXY = "github.alecsio.mmceaddons.CommonProxy";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,91 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;

import javax.annotation.Nonnull;

public class ContainerSingularityItemBus extends ContainerItemBus {

private static final int PLAYER_SLOT_COUNT = 36;
private static final int COUNT_PROPERTY_BASE = 0x4000;
private final int machineSlotCount;
private final boolean[] changedMachineSlots;
private final int[] pendingCountLow;

public ContainerSingularityItemBus(TileItemBus owner, EntityPlayer opening) {
super(owner, opening);
this.machineSlotCount = owner.getSize().getSlotCount();
this.changedMachineSlots = new boolean[this.machineSlotCount];
this.pendingCountLow = new int[this.machineSlotCount];
}

@Override
public void detectAndSendChanges() {
if (this.listeners.isEmpty()) {
super.detectAndSendChanges();
return;
}
for (int machineSlot = 0; machineSlot < this.machineSlotCount; machineSlot++) {
int containerSlot = PLAYER_SLOT_COUNT + machineSlot;
this.changedMachineSlots[machineSlot] = !ItemStack.areItemStacksEqual(this.inventoryItemStacks.get(containerSlot), this.inventorySlots.get(containerSlot).getStack());
}
super.detectAndSendChanges();
for (int machineSlot = 0; machineSlot < this.machineSlotCount; machineSlot++) {
if (!this.changedMachineSlots[machineSlot]) {
continue;
}
this.changedMachineSlots[machineSlot] = false;
ItemStack stack = this.inventorySlots.get(PLAYER_SLOT_COUNT + machineSlot).getStack();
int count = stack.getCount();
if (count <= Byte.MAX_VALUE) {
continue;
}
int property = COUNT_PROPERTY_BASE + machineSlot * 2;
for (IContainerListener listener : this.listeners) {
listener.sendWindowProperty(this, property, count & 0xFFFF);
listener.sendWindowProperty(this, property + 1, count >>> 16);
}
}
}

@Override
public void updateProgressBar(int id, int data) {
int property = id - COUNT_PROPERTY_BASE;
if (property < 0 || property >= this.machineSlotCount * 2) {
super.updateProgressBar(id, data);
return;
}
int machineSlot = property / 2;
if ((property & 1) == 0) {
this.pendingCountLow[machineSlot] = data & 0xFFFF;
return;
}
int count = this.pendingCountLow[machineSlot] | (data & 0xFFFF) << 16;
if (count <= Byte.MAX_VALUE) {
return;
}
Slot slot = this.inventorySlots.get(PLAYER_SLOT_COUNT + machineSlot);
if (!(slot instanceof SingularitySlotItemHandler)) {
return;
}
ItemStack stack = slot.getStack();
if (stack != ItemStack.EMPTY) {
stack.setCount(count);
}
}

int findRenderedMachineSlot(ItemStack stack, int x, int y) {
for (int machineSlot = 0; machineSlot < this.machineSlotCount; machineSlot++) {
Slot slot = this.inventorySlots.get(PLAYER_SLOT_COUNT + machineSlot);
if (slot instanceof SingularitySlotItemHandler && slot.xPos == x && slot.yPos == y && slot.getStack() == stack) {
return machineSlot;
}
}
return -1;
}

@Nonnull
@Override
Expand All @@ -41,4 +116,41 @@ public ItemStack slotClick(int slotId, int dragType, @Nonnull ClickType clickTyp
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
}

@Override
protected boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection) {
if (startIndex != PLAYER_SLOT_COUNT || endIndex != this.inventorySlots.size()) {
return super.mergeItemStack(stack, startIndex, endIndex, reverseDirection);
}
boolean changed = mergeIntoSingularitySlots(stack, startIndex, endIndex, reverseDirection, false);
if (!stack.isEmpty()) {
changed |= mergeIntoSingularitySlots(stack, startIndex, endIndex, reverseDirection, true);
}
return changed;
}

private boolean mergeIntoSingularitySlots(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection, boolean emptySlots) {
boolean changed = false;
int index = reverseDirection ? endIndex - 1 : startIndex;
while (!stack.isEmpty() && index >= startIndex && index < endIndex) {
Slot slot = this.inventorySlots.get(index);
ItemStack existing = slot.getStack();
if (slot instanceof SingularitySlotItemHandler singularitySlot
&& existing.isEmpty() == emptySlots
&& singularitySlot.getSlotStackLimit() > 0
&& (emptySlots || existing.getCount() < singularitySlot.getSlotStackLimit()
&& existing.isItemEqual(stack)
&& ItemStack.areItemStackTagsEqual(existing, stack))) {
int previousCount = stack.getCount();
ItemStack remainder = singularitySlot.insertItem(stack);
int remainingCount = remainder.isEmpty() ? 0 : remainder.getCount();
if (remainingCount < previousCount) {
stack.setCount(remainingCount);
changed = true;
}
}
index += reverseDirection ? -1 : 1;
}
return changed;
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,173 @@
package github.alecsio.mmceaddons.common.hatch.vanilla.gui;

import github.alecsio.mmceaddons.util.SingularitySlotItemHandler;
import hellfirepvp.modularmachinery.client.gui.GuiContainerBase;
import hellfirepvp.modularmachinery.common.block.prop.ItemBusSize;
import hellfirepvp.modularmachinery.common.container.ContainerItemBus;
import hellfirepvp.modularmachinery.common.tiles.base.TileItemBus;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextFormatting;

public class GuiContainerSingularityItemBus extends GuiContainerBase<ContainerItemBus> {
import javax.annotation.Nullable;
import java.text.NumberFormat;
import java.util.List;
import java.util.Locale;

public class GuiContainerSingularityItemBus extends GuiContainerBase<ContainerSingularityItemBus> {
private static CompactCountRenderItem compactCountRenderItem;
private static final NumberFormat EXACT_COUNT_FORMAT = NumberFormat.getIntegerInstance(Locale.US);
public GuiContainerSingularityItemBus(TileItemBus itemBus, EntityPlayer opening) {
super(new ContainerSingularityItemBus(itemBus, opening));
}
@Override
public void initGui() {
super.initGui();
RenderItem vanillaRenderItem = this.mc.getRenderItem();
if (compactCountRenderItem == null || !compactCountRenderItem.wraps(vanillaRenderItem)) {
compactCountRenderItem = new CompactCountRenderItem(this.mc, vanillaRenderItem);}
this.itemRender = compactCountRenderItem;
}

@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
compactCountRenderItem.setContainer(this.container);
try {super.drawScreen(mouseX, mouseY, partialTicks);
} finally {compactCountRenderItem.clearContainer(this.container);
}
}
private ResourceLocation getTextureInventory() {
ItemBusSize size = this.container.getOwner().getSize();
return new ResourceLocation("modularmachinery", "textures/gui/inventory_" + size.name().toLowerCase() + ".png");
}

protected void setWidthHeight() {
}

protected void setWidthHeight() {}
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(this.getTextureInventory());
int i = (this.width - this.xSize) / 2;
int j = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(i, j, 0, 0, this.xSize, this.ySize);
}
}

static String formatCompactCount(int count) {
if (count < 1_000) {return Integer.toString(count);}
int divisor;
char suffix;
if (count < 1_000_000) {
divisor = 1_000;
suffix = 'k';
} else if (count < 1_000_000_000) {
divisor = 1_000_000;
suffix = 'M';
} else {
divisor = 1_000_000_000;
suffix = 'B';
}
int whole = count / divisor;
if (whole >= 100) {return Integer.toString(whole) + suffix;}
int decimal = count % divisor / (divisor / 10);
if (decimal == 0) {return Integer.toString(whole) + suffix;}
return Integer.toString(whole) + '.' + decimal + suffix;
}

private static final class CompactCountRenderItem extends RenderItem {

private static final int CACHE_SIZE = ItemBusSize.LUDICROUS.getSlotCount();
private final RenderItem delegate;
private final int[] cachedCounts = new int[CACHE_SIZE];
private final String[] cachedText = new String[CACHE_SIZE];
private ContainerSingularityItemBus container;

private CompactCountRenderItem(Minecraft minecraft, RenderItem delegate) {
super(minecraft.getTextureManager(), delegate.getItemModelMesher().getModelManager(), minecraft.getItemColors());
this.delegate = delegate;
}

private boolean wraps(RenderItem renderItem) {return this.delegate == renderItem;}
private void setContainer(ContainerSingularityItemBus container) {this.container = container;}
private void clearContainer(ContainerSingularityItemBus container) {if (this.container == container) {
this.container = null;}
}

@Override
public void renderItemAndEffectIntoGUI(@Nullable EntityLivingBase entity, ItemStack stack, int x, int y) {
float previousZLevel = this.delegate.zLevel;
this.delegate.zLevel = this.zLevel;
try {
this.delegate.renderItemAndEffectIntoGUI(entity, stack, x, y);
} finally {
this.delegate.zLevel = previousZLevel;
}
}

@Override
public void renderItemOverlayIntoGUI(FontRenderer fontRenderer, ItemStack stack, int x, int y, @Nullable String text) {
float previousZLevel = this.delegate.zLevel;
this.delegate.zLevel = this.zLevel;
try {
if (text == null && stack.getCount() >= 1_000 && this.container != null) {
int machineSlot = this.container.findRenderedMachineSlot(stack, x, y);
if (machineSlot >= 0) {
this.delegate.renderItemOverlayIntoGUI(fontRenderer, stack, x, y, "");
drawCompactCount(fontRenderer, getCachedText(machineSlot, stack.getCount()), x, y);
return;
}
}
this.delegate.renderItemOverlayIntoGUI(fontRenderer, stack, x, y, text);
} finally {
this.delegate.zLevel = previousZLevel;
}
}

private String getCachedText(int machineSlot, int count) {
if (this.cachedText[machineSlot] == null || this.cachedCounts[machineSlot] != count) {
this.cachedCounts[machineSlot] = count;
this.cachedText[machineSlot] = formatCompactCount(count);
}
return this.cachedText[machineSlot];
}

private static void drawCompactCount(FontRenderer fontRenderer, String text, int x, int y) {
final float scale = 0.5F;
final float inverseScale = 1.0F / scale;
final int offset = -1;
boolean unicodeFlag = fontRenderer.getUnicodeFlag();
fontRenderer.setUnicodeFlag(false);
GlStateManager.disableLighting();
GlStateManager.disableDepth();
GlStateManager.disableBlend();
GlStateManager.pushMatrix();
try {
GlStateManager.scale(scale, scale, scale);
int drawX = (int) ((x + offset + 16.0F - fontRenderer.getStringWidth(text) * scale) * inverseScale);
int drawY = (int) ((y + offset + 16.0F - 7.0F * scale) * inverseScale);
fontRenderer.drawStringWithShadow(text, drawX, drawY, 0xFFFFFF);
} finally {
GlStateManager.popMatrix();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.enableBlend();
fontRenderer.setUnicodeFlag(unicodeFlag);
}
}
}
@Override
public List<String> getItemToolTip(ItemStack stack) {
List<String> tooltip = super.getItemToolTip(stack);
Slot hoveredSlot = this.getSlotUnderMouse();
if (stack.getCount() >= 1_000
&& hoveredSlot instanceof SingularitySlotItemHandler
&& hoveredSlot.getStack() == stack) {
tooltip.add(TextFormatting.GRAY + I18n.format("tooltip.modularmachineryaddons.singularity.stored", EXACT_COUNT_FORMAT.format(stack.getCount())));
}
return tooltip;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package github.alecsio.mmceaddons.common.mixin;

import github.alecsio.mmceaddons.common.hatch.vanilla.gui.ContainerSingularityItemBus;
import github.alecsio.mmceaddons.util.SingularitySlotItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
Expand All @@ -12,6 +13,8 @@ public class ContainerMixin {

@Redirect(method = "addInventorySlots(Lnet/minecraftforge/items/IItemHandlerModifiable;Lhellfirepvp/modularmachinery/common/block/prop/ItemBusSize;)V", at = @At(value = "NEW", target = "(Lnet/minecraftforge/items/IItemHandler;III)Lnet/minecraftforge/items/SlotItemHandler;"), remap=false)
public SlotItemHandler replaceSlotItemHandlers(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
return new SingularitySlotItemHandler(itemHandler, index, xPosition, yPosition);
if ((Object) this instanceof ContainerSingularityItemBus) {
return new SingularitySlotItemHandler(itemHandler, index, xPosition, yPosition);}
return new SlotItemHandler(itemHandler, index, xPosition, yPosition);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
import javax.annotation.Nonnull;

public class SingularitySlotItemHandler extends SlotItemHandler {
private final int handlerSlot;
public SingularitySlotItemHandler(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
super(itemHandler, index, xPosition, yPosition);
this.handlerSlot = index;
}

@Nonnull
public ItemStack insertItem(@Nonnull ItemStack stack) {
return this.getItemHandler().insertItem(this.handlerSlot, stack, false);
}
@Override
public int getItemStackLimit(@Nonnull ItemStack stack) {
return Integer.MAX_VALUE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ item.modularmachineryaddons.itemadvancedmachinedisassembler.name=Advanced Machin
item.modularmachineryaddons.itemradiationsponge.name=Radiation Sponge
item.modularmachineryaddons.iteminactiveradiationsponge.name=Inactive Radiation Sponge
tooltip.modularmachineryaddons.cheese.lie=The cheese is §llie
tooltip.modularmachineryaddons.singularity.stored=Stored: %s

commands.mmcea.getcacheinfo.usage=/getScrubbedChunksCacheInfo

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ item.modularmachineryaddons.itemadvancedmachinedisassembler.name=高级机械拆
item.modularmachineryaddons.itemradiationsponge.name=辐射海绵
item.modularmachineryaddons.iteminactiveradiationsponge.name=未激活的辐射海绵
tooltip.modularmachineryaddons.cheese.lie=奶酪是个§l谎言
tooltip.modularmachineryaddons.singularity.stored=已储存:%s

commands.mmcea.getcacheinfo.usage=/getScrubbedChunksCacheInfo

Expand Down