feat: Basic gui

This commit is contained in:
Discreater committed 2021-04-26 14:26:06 +08:00
1 parent 5283b0641f
commit 42bf760bcb
57 files changed
+2705 -600

No files matched your search

@@ -10,11 +10,17 @@ public class JecaConfig {
public static boolean initialized = false;
public static Configuration config;
public static boolean isForceClient() {
return EnumItems.ForceClient.getProperty().getBoolean();
}
public enum EnumItems {
EnableInventoryCheck, ListRecipeBlackList, ListRecipeCategory;
ForceClient, EnableInventoryCheck, ListRecipeBlackList, ListRecipeCategory;
public String getComment() {
switch (this) {
case ForceClient:
return "Set to true to force client mode: no item and recipe allowed, use key bindings instead.";
case EnableInventoryCheck:
return "Set to false to disable auto inventory check";
case ListRecipeBlackList:
@@ -28,6 +34,8 @@ public class JecaConfig {
public String getName() {
switch (this) {
case ForceClient:
return "ForceClient";
case EnableInventoryCheck:
return "EnableInventoryCheck";
case ListRecipeBlackList:
@@ -40,6 +48,7 @@ public class JecaConfig {
public String getCategory() {
switch (this) {
case ForceClient:
case EnableInventoryCheck:
case ListRecipeBlackList:
case ListRecipeCategory:
@@ -50,6 +59,7 @@ public class JecaConfig {
public EnumType getType() {
switch (this) {
case ForceClient:
case EnableInventoryCheck:
return EnumType.Boolean;
case ListRecipeBlackList:
@@ -61,6 +71,8 @@ public class JecaConfig {
public Object getDefault() {
switch (this) {
case ForceClient:
return false;
case EnableInventoryCheck:
return true;
case ListRecipeBlackList:
@@ -1,32 +0,0 @@
package me.towdium.jecalculation;
import me.towdium.jecalculation.gui.GuiHandler;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author Towdium
*/
public class JecaItem extends Item {
public static JecaItem INSTANCE = new JecaItem();
public static final String NAME = "itemCalculator";
public JecaItem() {
setHasSubtypes(true);
setMaxStackSize(1);
setUnlocalizedName(NAME);
setTextureName(JustEnoughCalculation.Reference.MODID + ":" + NAME);
setCreativeTab(CreativeTabs.tabTools);
}
@Override
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn) {
playerIn.openGui(JustEnoughCalculation.INSTANCE, GuiHandler.GuiId.EDITOR, worldIn, 0, 0, 0);
return itemStackIn;
}
}
@@ -5,20 +5,28 @@ import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.network.NetworkCheckHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import cpw.mods.fml.common.registry.GameRegistry;
import me.towdium.jecalculation.gui.GuiHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.command.JecaCommand;
import me.towdium.jecalculation.nei.NEIPlugin;
import me.towdium.jecalculation.network.IProxy;
import me.towdium.jecalculation.network.ProxyCommon;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Map;
/**
* @author Towdium
*/
@ParametersAreNonnullByDefault
@SuppressWarnings("unused")
@SideOnly(Side.CLIENT)
@Mod(modid = JustEnoughCalculation.Reference.MODID,
name = JustEnoughCalculation.Reference.MODNAME,
version = JustEnoughCalculation.Reference.VERSION,
@@ -29,35 +37,70 @@ public class JustEnoughCalculation {
@SidedProxy(modId = Reference.MODID,
clientSide = "me.towdium.jecalculation.network.ProxyClient",
serverSide = "me.towdium.jecalculation.network.ProxyServer")
public static IProxy proxy;
serverSide = "me.towdium.jecalculation.network.ProxyCommon")
public static ProxyCommon proxy;
public static SimpleNetworkWrapper network;
public static Logger logger = LogManager.getLogger(Reference.MODID);
public static enumSide side = enumSide.UNDEFINED;
@NetworkCheckHandler
public static boolean networkCheck(Map<String, String> mods, Side s) {
if (s == Side.SERVER) {
if (mods.containsKey(Reference.MODID) && !JecaConfig.isForceClient()) {
side = enumSide.BOTH;
} else {
side = enumSide.CLIENT;
}
} else {
if (mods.containsKey(Reference.MODID)) {
side = enumSide.SERVER;
} else {
return false;
}
}
return true;
}
@Mod.EventHandler
public static void preInit(FMLPreInitializationEvent event) {
public static void initPre(FMLPreInitializationEvent event) {
JecaConfig.preInit(event);
GameRegistry.registerItem(JecaItem.INSTANCE, JecaItem.NAME);
network = NetworkRegistry.INSTANCE.newSimpleChannel(Reference.MODID);
proxy.preInit();
proxy.initPre();
}
@Mod.EventHandler
public static void init(FMLInitializationEvent event) {
NetworkRegistry.INSTANCE.registerGuiHandler(INSTANCE, new GuiHandler());
proxy.init();
}
@Mod.EventHandler
public static void postInit(FMLPostInitializationEvent event) {
proxy.initPost();
NEIPlugin.init();
}
@Mod.EventHandler
public static void onServerStart(FMLServerStartingEvent event) {
if (side == enumSide.SERVER) {
event.registerServerCommand(new JecaCommand());
}
}
public static class Reference {
public static final String MODID = "jecalculation";
public static final String MODNAME = "Just Enough Calculation";
public static final String VERSION = "@VERSION@";
}
/**
* CLIENT: running at client side and server not installed
* SERVER: running at server side whether client is installed
* BOTH: running at client side and both installed
* UNDEFINED: default unknown
*/
public enum enumSide {
CLIENT, SERVER, BOTH, UNDEFINED
}
}
@@ -0,0 +1,132 @@
package me.towdium.jecalculation.client.gui;
import cpw.mods.fml.client.config.GuiUtils;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.client.resource.Resource;
import me.towdium.jecalculation.client.widget.Widget;
import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
/**
* Author: towdium
* Date: 8/12/17.
*/
@ParametersAreNonnullByDefault
public class JecGui extends GuiContainer {
public List<GuiButton> buttonList = super.buttonList;
public WidgetManager widgetManager = new WidgetManager();
GuiScreen parent;
public JecGui(@Nullable GuiScreen parent) {
super(new Container() {
@Override
public boolean canInteractWith(EntityPlayer playerIn) {
return true;
}
});
this.parent = parent;
}
@Override
public void initGui() {
super.initGui();
widgetManager.onInit();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
GlStateManager.disableLighting();
widgetManager.onDraw(mouseX, mouseY);
GlStateManager.enableLighting();
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
drawTexture(new ResourceLocation(JustEnoughCalculation.Reference.MODID,
"textures/gui/" + getBackground() + ".png"), guiLeft, guiTop, 0, 0, this.xSize, this.ySize);
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
// here I haven't copied the event thingy, don't think anyone will use it
widgetManager.onClick(mouseX, mouseY, mouseButton);
}
// new functions
public void drawResource(Resource r, int xPos, int yPos) {
drawTexture(Resource.location, xPos, yPos, r.getXPos(), r.getYPos(), r.getXSize(), r.getYSize());
}
public void drawResourceContinuous(
Resource r, int xPos, int yPos, int xSize, int ySize,
int borderTop, int borderBottom, int borderLeft, int borderRight) {
drawTextureContinuous(Resource.location, xPos, yPos, xSize, ySize,
r.getXPos(), r.getYPos(), r.getXSize(), r.getYSize(),
borderTop, borderBottom, borderLeft, borderRight);
}
public void drawTexture(ResourceLocation l, int destXPos, int destYPos,
int sourceXPos, int sourceYPos, int sourceXSize, int sourceYSize) {
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(l);
this.drawTexturedModalRect(destXPos, destYPos, sourceXPos, sourceYPos, sourceXSize, sourceYSize);
}
public void drawTextureContinuous(
ResourceLocation l, int destXPos, int destYPos, int destXSize, int destYSize,
int sourceXPos, int sourceYPos, int sourceXSize, int sourceYSize,
int borderTop, int borderBottom, int borderLeft, int borderRight) {
GuiUtils.drawContinuousTexturedBox(l, destXPos, destYPos, sourceXPos, sourceYPos, destXSize, destYSize,
sourceXSize, sourceYSize, borderTop, borderBottom, borderLeft, borderRight, zLevel);
}
protected String getBackground() {
return "error";
}
public class WidgetManager {
protected List<Widget> widgets = new ArrayList<>();
public void add(Widget w) {
widgets.add(w);
}
public void remove(Widget w) {
widgets.remove(w);
w.onRemoved(JecGui.this);
}
public void onInit() {
widgets.forEach(w -> w.onGuiInit(JecGui.this));
}
public void onDraw(int mouseX, int mouseY) {
widgets.forEach(widget -> widget.onDraw(JecGui.this, mouseX, mouseY));
}
public void onClick(int xMouse, int yMouse, int button) {
widgets.forEach(w -> w.onClicked(JecGui.this, xMouse, yMouse, button));
}
}
public int getGuiLeft() { return guiLeft; }
public int getGuiTop() { return guiTop; }
}
@@ -0,0 +1,35 @@
package me.towdium.jecalculation.client.gui.guis;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.resource.Resource;
import me.towdium.jecalculation.client.widget.widgets.WButtonIcon;
import me.towdium.jecalculation.client.widget.widgets.WEntryGroup;
import me.towdium.jecalculation.client.widget.widgets.WLine;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
/**
* Author: towdium
* Date: 8/14/17.
*/
@ParametersAreNonnullByDefault
public class GuiCalculator extends JecGui {
public GuiCalculator(@Nullable GuiScreen parent) {
super(parent);
widgetManager.add(new WButtonIcon(7, 7, Resource.LABEL_NORMAL, Resource.LABEL_FOCUSED)
.setListenerLeft(() -> Minecraft.getMinecraft().displayGuiScreen(null))
.setListenerRight(() -> Minecraft.getMinecraft().displayGuiScreen(null)));
widgetManager.add(new WButtonIcon(130, 7, Resource.NEW_NORMAL, Resource.NEW_FOCUSED));
widgetManager.add(new WButtonIcon(149, 7, Resource.SEARCH_NORMAL, Resource.SEARCH_FOCUSED));
widgetManager.add(new WEntryGroup(7, 87, 9, 4));
widgetManager.add(new WLine(52));
}
@Override
protected String getBackground() {
return "gui_calculator";
}
}
@@ -0,0 +1,48 @@
package me.towdium.jecalculation.client.resource;
import me.towdium.jecalculation.JustEnoughCalculation;
import net.minecraft.util.ResourceLocation;
/**
* Author: towdium
* Date: 17-8-17.
*/
public class Resource {
public static final ResourceLocation location = new ResourceLocation(
JustEnoughCalculation.Reference.MODID, "textures/gui/resources.png");
public static final Resource LABEL_NORMAL = new Resource(0, 14, 14, 14);
public static final Resource LABEL_FOCUSED = new Resource(0, 0, 14, 14);
public static final Resource NEW_NORMAL = new Resource(14, 14, 14, 14);
public static final Resource NEW_FOCUSED = new Resource(14, 0, 14, 14);
public static final Resource SEARCH_NORMAL = new Resource(28, 14, 14, 14);
public static final Resource SEARCH_FOCUSED = new Resource(28, 0, 14, 14);
public static final Resource BUTTON_NORMAL = new Resource(216, 0, 20, 20);
public static final Resource BUTTON_FOCUSED = new Resource(236, 0, 20, 20);
public static final Resource SLOT = new Resource(196, 0, 20, 20);
public static final Resource LINE = new Resource(0, 28, 163, 4);
protected int xPos, yPos, xSize, ySize;
public Resource(int xPos, int yPos, int xSize, int ySize) {
this.xPos = xPos;
this.yPos = yPos;
this.xSize = xSize;
this.ySize = ySize;
}
public int getXPos() {
return xPos;
}
public int getYPos() {
return yPos;
}
public int getXSize() {
return xSize;
}
public int getYSize() {
return ySize;
}
}
@@ -0,0 +1,22 @@
package me.towdium.jecalculation.client.widget;
import me.towdium.jecalculation.client.gui.JecGui;
import net.minecraft.client.gui.Gui;
/**
* Author: towdium
* Date: 8/14/17.
*/
public class Widget extends Gui {
public void onGuiInit(JecGui gui) {
}
public void onDraw(JecGui gui, int xMouse, int yMouse) {
}
public void onRemoved(JecGui gui) {
}
public void onClicked(JecGui gui, int xMouse, int yMouse, int button) {
}
}
@@ -0,0 +1,57 @@
package me.towdium.jecalculation.client.widget.widgets;
import cpw.mods.fml.client.config.GuiButtonExt;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.widget.Widget;
import me.towdium.jecalculation.utils.ClientUtils;
import net.minecraft.client.Minecraft;
/**
* Author: towdium
* Date: 8/14/17.
*/
public class WButton extends Widget {
protected int xPos, yPos, xSize, ySize;
protected Runnable lsnrLeft, lsnrRight;
protected String text;
protected GuiButtonExt button;
public WButton(int xPos, int yPos, int xSize, int ySize, String text) {
this.xPos = xPos;
this.yPos = yPos;
this.xSize = xSize;
this.ySize = ySize;
this.text = text;
}
public WButton setListenerLeft(Runnable r) {
lsnrLeft = r;
return this;
}
public WButton setListenerRight(Runnable r) {
lsnrRight = r;
return this;
}
@Override
public void onGuiInit(JecGui gui) {
super.onGuiInit(gui);
button = new GuiButtonExt(0, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(), xSize, ySize, text);
gui.buttonList.add(button);
}
@Override
public void onClicked(JecGui gui, int xMouse, int yMouse, int button) {
if (this.button.mousePressed(Minecraft.getMinecraft(), xMouse, yMouse)) {
if (button == 0 && lsnrLeft != null) {
lsnrLeft.run();
ClientUtils.playClickSound(1.0F);
} else if (button == 1 && lsnrRight != null) {
lsnrLeft.run();
ClientUtils.playClickSound(0.8F);
}
}
}
}
@@ -0,0 +1,46 @@
package me.towdium.jecalculation.client.widget.widgets;
import cpw.mods.fml.client.config.GuiButtonExt;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.resource.Resource;
import net.minecraft.client.Minecraft;
/**
* Author: towdium
* Date: 17-8-17.
*/
public class WButtonIcon extends WButton {
protected int xPos, yPos;
protected Resource normal, focused;
public WButtonIcon(int xPos, int yPos, Resource normal, Resource focused) {
super(xPos, yPos, 20, 20, "");
this.xPos = xPos;
this.yPos = yPos;
this.normal = normal;
this.focused = focused;
}
@Override
public void onGuiInit(JecGui gui) {
super.onGuiInit(gui);
gui.buttonList.add(new GuiButtonExt(0, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(), 20, 20, "") {
@Override
public void drawButton(Minecraft mc, int mouseX, int mouseY) {
final int x = this.xPosition;
final int y = this.yPosition;
this.field_146123_n = mouseX > x + 1 && mouseY > y + 1 && mouseX <= x + width - 1 && mouseY <= y + height - 1;
boolean hovered = this.field_146123_n;
gui.drawResource(hovered ? Resource.BUTTON_FOCUSED : Resource.BUTTON_NORMAL, x, y);
String text = displayString;
int strWidth = mc.fontRenderer.getStringWidth(text);
int ellipsisWidth = mc.fontRenderer.getStringWidth("...");
if (strWidth > width - 6 && strWidth > ellipsisWidth)
text = mc.fontRenderer.trimStringToWidth(text, width - 6 - ellipsisWidth).trim() + "...";
this.drawCenteredString(mc.fontRenderer, text, x + this.width / 2, y + (this.height - 8) / 2,
hovered ? 16777120 : 14737632);
gui.drawResource(hovered ? focused : normal, x + 3, y + 3);
}
});
}
}
@@ -0,0 +1,44 @@
package me.towdium.jecalculation.client.widget.widgets;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.resource.Resource;
import me.towdium.jecalculation.client.widget.Widget;
import me.towdium.jecalculation.core.entry.Entry;
/**
* Author: towdium
* Date: 17-8-17.
*/
public class WEntry extends Widget {
protected int xPos, yPos, xSize, ySize;
protected Entry entry;
public WEntry(int xPos, int yPos, int xSize, int ySize) {
this.xPos = xPos;
this.yPos = yPos;
this.xSize = xSize;
this.ySize = ySize;
}
public Entry getEntry() {
return entry;
}
public void setEntry(Entry entry) {
this.entry = entry;
}
@Override
public void onDraw(JecGui gui, int xMouse, int yMouse) {
gui.drawResourceContinuous(Resource.SLOT, xPos + gui.getGuiLeft(), yPos + gui.getGuiTop(),
xSize, ySize, 3, 3, 3, 3);
if (mouseIn(gui, xMouse, yMouse)) drawRect(gui.getGuiLeft() + xPos + 1, gui.getGuiTop() + yPos + 1,
gui.getGuiLeft() + xPos + xSize - 1, gui.getGuiTop() + yPos + ySize - 1, 0x80FFFFFF);
}
public boolean mouseIn(JecGui gui, int x, int y) {
int xx = x - gui.getGuiLeft() - xPos;
int yy = y - gui.getGuiTop() - yPos;
return xx >= 0 && xx < xSize && yy >= 0 && yy < ySize;
}
}
@@ -0,0 +1,44 @@
package me.towdium.jecalculation.client.widget.widgets;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.widget.Widget;
import java.util.ArrayList;
import java.util.stream.IntStream;
/**
* Author: towdium
* Date: 17-8-17.
*/
public class WEntryGroup extends Widget {
ArrayList<WEntry> widgets = new ArrayList<>();
public WEntryGroup(int xPos, int yPos, int column, int row) {
this(xPos, yPos, column, row, 18, 18);
}
public WEntryGroup(int xPos, int yPos, int column, int row, int xSize, int ySize) {
IntStream.range(0, column).forEach(c -> IntStream.range(0, row).forEach(r ->
widgets.add(new WEntry(xPos + c * xSize, yPos + r * ySize, xSize, ySize))));
}
@Override
public void onGuiInit(JecGui gui) {
widgets.forEach(w -> w.onGuiInit(gui));
}
@Override
public void onDraw(JecGui gui, int xMouse, int yMouse) {
widgets.forEach(w -> w.onDraw(gui, xMouse, yMouse));
}
@Override
public void onRemoved(JecGui gui) {
widgets.forEach(w -> w.onRemoved(gui));
}
@Override
public void onClicked(JecGui gui, int xMouse, int yMouse, int button) {
widgets.forEach(w -> w.onClicked(gui, xMouse, yMouse, button));
}
}
@@ -0,0 +1,22 @@
package me.towdium.jecalculation.client.widget.widgets;
import me.towdium.jecalculation.client.gui.JecGui;
import me.towdium.jecalculation.client.resource.Resource;
import me.towdium.jecalculation.client.widget.Widget;
/**
* Author: towdium
* Date: 17-8-18.
*/
public class WLine extends Widget {
protected int y;
public WLine(int y) {
this.y = y;
}
@Override
public void onDraw(JecGui gui, int xMouse, int yMouse) {
gui.drawResource(Resource.LINE, 6 + gui.getGuiLeft(), y + gui.getGuiTop() - 1);
}
}
@@ -0,0 +1,30 @@
package me.towdium.jecalculation.command;
import me.towdium.jecalculation.command.commands.CommandHelp;
import me.towdium.jecalculation.command.commands.CommandState;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.HashMap;
/**
* Author: towdium
* Date: 8/10/17.
*/
@ParametersAreNonnullByDefault
public class Commands {
public static final HashMap<String, SubCommand> commands;
public static final CommandHelp commandHelp = new CommandHelp();
public static final CommandState commandState = new CommandState();
static {
commands = new HashMap<>();
add(commandHelp);
add(commandState);
}
static void add(SubCommand c) {
commands.put(c.getName(), c);
}
}
@@ -0,0 +1,69 @@
package me.towdium.jecalculation.command;
import me.towdium.jecalculation.utils.wrappers.Single;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentTranslation;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collections;
import java.util.List;
/**
* Author: towdium
* Date: 8/10/17.
*/
@ParametersAreNonnullByDefault
public class JecaCommand extends CommandBase {
@Override
public String getCommandName() {
return "jec";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/jec [help]";
}
@Override
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
if (args.length == 0 || args[0].toLowerCase().equals("help")) {
Commands.commandHelp.execute(sender, cut(args));
} else {
SubCommand cmd = Commands.commands.get(args[0].toLowerCase());
if (cmd != null) {
cmd.execute(sender, args);
} else {
sender.addChatMessage(new ChatComponentTranslation("command.not_found", args[0]));
}
}
}
private String[] cut(String[] args) {
if (args.length == 0)
return new String[0];
String[] ret = new String[args.length - 1];
System.arraycopy(args, 1, ret, 0, args.length - 1);
return ret;
}
@Override
public List<String> addTabCompletionOptions(ICommandSender sender, String[] args) {
if (args.length == 0) {
return Collections.emptyList();
}
String cmd = args[0].toLowerCase();
if (args.length == 1) {
return getListOfStringsFromIterableMatchingLastWord(args, Commands.commands.keySet());
} else {
Single<SubCommand> sub = new Single<>(null);
Commands.commands.values().stream().filter(c -> c.getName().equals(cmd))
.findFirst().ifPresent(sub::push);
return sub.value == null ? sub.value.getTabCompletions(sender, cut(args))
: Collections.emptyList();
}
}
}
@@ -0,0 +1,26 @@
package me.towdium.jecalculation.command;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Collections;
import java.util.List;
/**
* Author: towdium
* Date: 8/10/17.
*/
@ParametersAreNonnullByDefault
public interface SubCommand {
String getName();
String getUsage(ICommandSender sender);
void execute(ICommandSender sender, String[] args) throws CommandException;
@SuppressWarnings("unused")
default List<String> getTabCompletions(ICommandSender sender, String[] args) {
return Collections.emptyList();
}
}
@@ -0,0 +1,40 @@
package me.towdium.jecalculation.command.commands;
import me.towdium.jecalculation.command.Commands;
import me.towdium.jecalculation.command.SubCommand;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatComponentTranslation;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Comparator;
/**
* Author: towdium
* Date: 8/10/17.
*/
@ParametersAreNonnullByDefault
public class CommandHelp implements SubCommand {
@Override
public String getName() {
return "help";
}
@Override
public String getUsage(ICommandSender sender) {
return "/jec [help]";
}
@Override
public void execute(ICommandSender sender, String[] args) throws CommandException {
if (args.length != 0) {
sender.addChatMessage(new ChatComponentTranslation("command.unexpected_arg", String.join(" ", args)));
return;
}
sender.addChatMessage(new ChatComponentTranslation("command.help.list"));
Commands.commands.values().stream().sorted(Comparator.comparing(SubCommand::getName))
.forEachOrdered(c -> sender.addChatMessage(new ChatComponentText(c.getUsage(sender))));
}
}
@@ -0,0 +1,33 @@
package me.towdium.jecalculation.command.commands;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.command.SubCommand;
import me.towdium.jecalculation.utils.helpers.LocalizationHelper;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.ChatComponentTranslation;
import javax.annotation.ParametersAreNonnullByDefault;
/**
* Author: towdium
* Date: 8/10/17.
*/
@ParametersAreNonnullByDefault
public class CommandState implements SubCommand {
@Override
public String getName() {
return "state";
}
@Override
public String getUsage(ICommandSender sender) {
return "/jec state";
}
@Override
public void execute(ICommandSender sender, String[] args) throws CommandException {
sender.addChatMessage(new ChatComponentTranslation("command.state.desc",
LocalizationHelper.format(JustEnoughCalculation.side.toString())));
}
}
@@ -0,0 +1,143 @@
package me.towdium.jecalculation.core.entry;
import me.towdium.jecalculation.core.entry.entries.EntryItemStack;
import me.towdium.jecalculation.utils.wrappers.Pair;
import me.towdium.jecalculation.utils.wrappers.Single;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import java.util.HashMap;
import java.util.Optional;
import java.util.function.Function;
/**
* Author: towdium
* Date: 8/11/17.
*/
public interface Entry {
EntryMerger MERGER = EntryMerger.INSTANCE;
EntryRegistry REGISTRY = EntryRegistry.INSTANCE;
Entry EMPTY = new EntryItemStack(new ItemStack(new Item()), 0);
int getAmount();
void setAmount(int amount);
ItemStack getRepresentation();
String getAmountString();
/**
* Since {@link Entry} merging is bidirectional, it is redundant to
* implement on both side. So this class is created for merging
* {@link Entry Entry(s)}.
* It uses singleton mode. First register merge functions, then use
* {@link #test(Entry, Entry)} and {@link #merge(Entry, Entry, boolean)}
* to operate the {@link Entry}.
* For registering, see {@link EntryRegistry}.
*/
class EntryMerger {
private static final EntryMerger INSTANCE;
static {
INSTANCE = new EntryMerger();
// register functions here
}
private Relation<String, MergerFunction> functions = new Relation<>();
private EntryMerger() {
}
public void addFunction(String a, String b, MergerFunction func) {
functions.add(a, b, func);
}
public Pair<Entry, Entry> merge(Entry a, Entry b, boolean add) {
return functions.get(REGISTRY.getIdentifier(a), REGISTRY.getIdentifier(b))
.orElse((x, y, f) -> new Pair<>(x, y)).merge(a, b, add);
}
public boolean test(Entry a, Entry b) {
Optional<MergerFunction> f = functions.get(REGISTRY.getIdentifier(a), REGISTRY.getIdentifier(b));
if (!f.isPresent()) return false;
else {
Pair<Entry, Entry> p = f.get().merge(a, b, true);
return (!(p.one == a && p.two == b) && !(p.two == a && p.one == a));
}
}
@FunctionalInterface
public interface MergerFunction {
/**
* @param a an {@link Entry} to merge
* @param b another {@link Entry} to merge
* @param add add together or cancel each other
* @return merged {@link Entry Entry(s)} if not changed (no matter order), they cannot merge.
*/
Pair<Entry, Entry> merge(Entry a, Entry b, boolean add);
}
}
/**
* This class is used to register an {@link Entry} type.
* Here you can find the identifier and deserializer of one type.
* For {@link Entry} operations, see {@link EntryMerger}
*/
class EntryRegistry {
public static final String KEY_IDENTIFIER = "identifier";
public static final String KEY_CONTENT = "content";
private static final EntryRegistry INSTANCE;
static {
INSTANCE = new EntryRegistry();
}
private HashMap<Class<? extends Entry>, Pair<String,
Function<NBTTagCompound, Optional<Entry>>>> clazzToData = new HashMap<>();
private HashMap<String, Pair<Class<? extends Entry>,
Function<NBTTagCompound, Optional<Entry>>>> idToData = new HashMap<>();
private EntryRegistry() {
}
public <T extends Entry> void register(
Class<T> clazz, String identifier, Function<NBTTagCompound, Optional<Entry>> deserializer) {
clazzToData.put(clazz, new Pair<>(identifier, deserializer));
idToData.put(identifier, new Pair<>(clazz, deserializer));
}
public Entry deserialization(NBTTagCompound nbt) {
String s = nbt.getString(KEY_IDENTIFIER);
Optional<Entry> e = idToData.get(s).two.apply(nbt.getCompoundTag(KEY_CONTENT));
if (e.isPresent()) return e.get();
else throw new RuntimeException("Fail to deserialize entry type: " + s);
}
public String getIdentifier(Entry e) {
Pair<String, Function<NBTTagCompound, Optional<Entry>>> p = clazzToData.get(e.getClass());
if (p == null) throw new RuntimeException("Unregistered entry type: " + e.getClass());
else return p.one;
}
}
class Relation<T, R> {
HashMap<Pair<T, T>, R> data = new HashMap<>();
public void add(T a, T b, R relation) {
data.put(a.hashCode() < b.hashCode() ? new Pair<>(a, b) : new Pair<>(b, a), relation);
}
public Optional<R> get(T a, T b) {
int ah = a.hashCode();
int bh = b.hashCode();
Single<R> ret = new Single<>(null);
if (ah == bh)
ret.push(data.get(new Pair<>(a, b))).push(data.get(new Pair<>(b, a)));
else
ret.push(data.get(ah < bh ? new Pair<>(a, b) : new Pair<>(b, a)));
return Optional.ofNullable(ret.value);
}
}
}
@@ -0,0 +1,39 @@
package me.towdium.jecalculation.core.entry.entries;
import me.towdium.jecalculation.core.entry.Entry;
import net.minecraft.item.ItemStack;
/**
* Author: towdium
* Date: 8/11/17.
*/
public class EntryItemStack implements Entry {
int amount;
ItemStack itemStack;
// I will copy it!
public EntryItemStack(ItemStack is, int amount) {
itemStack = is.copy();
this.amount = amount;
}
@Override
public int getAmount() {
return amount;
}
@Override
public void setAmount(int amount) {
this.amount = amount;
}
@Override
public ItemStack getRepresentation() {
return itemStack;
}
@Override
public String getAmountString() {
return Integer.toString(amount); // TODO format
}
}
@@ -0,0 +1,15 @@
package me.towdium.jecalculation.event;
import me.towdium.jecalculation.event.handlers.InputEventHandler;
import java.util.ArrayList;
public class Handlers {
public static final ArrayList<Object> handlers;
static {
handlers = new ArrayList<>();
handlers.add(new InputEventHandler());
}
}
@@ -0,0 +1,27 @@
package me.towdium.jecalculation.event.handlers;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.client.gui.guis.GuiCalculator;
import me.towdium.jecalculation.network.ProxyClient;
import net.minecraft.client.Minecraft;
/**
* Author: towdium
* Date: 8/13/17.
*/
public class InputEventHandler {
@SideOnly(Side.CLIENT)
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public void onKey(InputEvent.KeyInputEvent event) {
if (ProxyClient.keyOpenGui.isPressed() && JustEnoughCalculation.side != JustEnoughCalculation.enumSide.SERVER) {
JustEnoughCalculation.logger.info("key pressed");
Minecraft.getMinecraft().displayGuiScreen(new GuiCalculator(null));
}
}
}
@@ -1,7 +1,7 @@
package me.towdium.jecalculation.gui;
import me.towdium.jecalculation.utils.ItemStackHelper;
import me.towdium.jecalculation.utils.polyfill.ClickType;
import me.towdium.jecalculation.polyfill.ClickType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryBasic;
@@ -1,7 +1,7 @@
package me.towdium.jecalculation.gui;
import me.towdium.jecalculation.utils.ItemStackHelper;
import me.towdium.jecalculation.utils.polyfill.SoundEvents;
import me.towdium.jecalculation.polyfill.SoundEvents;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
@@ -9,7 +9,6 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
@@ -97,7 +97,7 @@ public class GuiCalculator extends JecaGuiContainer {
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(
new ResourceLocation(JustEnoughCalculation.Reference.MODID, "textures/gui/guiCalculator.png"));
new ResourceLocation(JustEnoughCalculation.Reference.MODID, "textures/gui/gui_calculator.png"));
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
textFieldAmount.drawTextBox();
}
@@ -0,0 +1,17 @@
package me.towdium.jecalculation.item;
import me.towdium.jecalculation.item.items.ItemCalculator;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
@ParametersAreNonnullByDefault
public class Items {
public static final ArrayList<JecaItem> items;
public static final ItemCalculator itemCalculator = new ItemCalculator();
static {
items = new ArrayList<>();
items.add(itemCalculator);
}
}
@@ -0,0 +1,44 @@
package me.towdium.jecalculation.item;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.gui.GuiHandler;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* @author Towdium
*/
public class JecaItem extends Item {
public static JecaItem INSTANCE = new JecaItem();
public static final String CRAFTING_NAME = "item_calculator_crafting";
public static final String MATH_NAME = "item_calculator_math";
public JecaItem() {
setHasSubtypes(true);
setMaxStackSize(1);
setUnlocalizedName(CRAFTING_NAME);
setTextureName(JustEnoughCalculation.Reference.MODID + ":" + CRAFTING_NAME);
setCreativeTab(CreativeTabs.tabTools);
}
// @Override
// public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn) {
// playerIn.openGui(JustEnoughCalculation.INSTANCE, GuiHandler.GuiId.EDITOR, worldIn, 0, 0, 0);
// return itemStackIn;
// }
public String getUnlocalizedName(int meta) {
return getUnlocalizedName();
}
@Override
public String getUnlocalizedName(ItemStack stack) {
return getUnlocalizedName(stack.getItemDamage());
}
}
@@ -0,0 +1,40 @@
package me.towdium.jecalculation.item.items;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.item.JecaItem;
import me.towdium.jecalculation.utils.IllegalPositionException;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import java.util.List;
public class ItemCalculator extends JecaItem {
public ItemCalculator() {
setHasSubtypes(true);
setMaxStackSize(1);
setCreativeTab(CreativeTabs.tabTools);
setUnlocalizedName("item_calculator");
setTextureName(JustEnoughCalculation.Reference.MODID + ":" + CRAFTING_NAME);
}
@Override
public String getUnlocalizedName(int meta) {
switch (meta) {
case 0:
return "item.item_calculator_crafting";
case 1:
return "item.item_calculator_math";
default:
throw new IllegalPositionException();
}
}
@Override
public void getSubItems(Item item, CreativeTabs tab, List items) {
if (tab == CreativeTabs.tabAllSearch || tab == CreativeTabs.tabTools) {
items.add(new ItemStack(this, 1, 0));
items.add(new ItemStack(this, 1, 1));
}
}
}
@@ -1,8 +0,0 @@
package me.towdium.jecalculation.network;
public interface IProxy {
void preInit();
void init();
}
@@ -1,21 +1,28 @@
package me.towdium.jecalculation.network;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cpw.mods.fml.client.registry.ClientRegistry;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.gui.GuiHandler;
import me.towdium.jecalculation.command.JecaCommand;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.client.ClientCommandHandler;
import org.lwjgl.input.Keyboard;
public class ProxyClient extends ProxyCommon{
public static final KeyBinding keyOpenGui =
new KeyBinding("key.open_gui", Keyboard.KEY_F, "key.category");
@SideOnly(Side.CLIENT)
public class ProxyClient implements IProxy {
@Override
public void preInit() {
public void initPost() {
super.initPost();
JustEnoughCalculation.logger.info("client proxy init post");
ClientCommandHandler.instance.registerCommand(new JecaCommand());
}
@Override
public void init() {
NetworkRegistry.INSTANCE.registerGuiHandler(JustEnoughCalculation.INSTANCE, new GuiHandler());
super.init();
JustEnoughCalculation.logger.info("client proxy init");
ClientRegistry.registerKeyBinding(keyOpenGui);
}
}
@@ -0,0 +1,24 @@
package me.towdium.jecalculation.network;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.event.Handlers;
import me.towdium.jecalculation.item.JecaItem;
import net.minecraftforge.common.MinecraftForge;
public class ProxyCommon {
public void initPre() {
JustEnoughCalculation.logger.info("common proxy init pre");
GameRegistry.registerItem(JecaItem.INSTANCE, JecaItem.CRAFTING_NAME);
Handlers.handlers.forEach(FMLCommonHandler.instance().bus()::register);
}
public void init() {
JustEnoughCalculation.logger.info("common proxy init");
}
public void initPost() {
JustEnoughCalculation.logger.info("common proxy init post");
}
}
@@ -1,14 +0,0 @@
package me.towdium.jecalculation.network;
public class ProxyServer implements IProxy {
@Override
public void preInit() {
}
@Override
public void init() {
}
}
@@ -1,4 +1,4 @@
package me.towdium.jecalculation.utils.polyfill;
package me.towdium.jecalculation.polyfill;
public class ClickType {
public static final int PICKUP = 0;
@@ -1,4 +1,4 @@
package me.towdium.jecalculation.utils.polyfill;
package me.towdium.jecalculation.polyfill;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -1,4 +1,4 @@
package me.towdium.jecalculation.utils.polyfill;
package me.towdium.jecalculation.polyfill;
public class SoundEvents {
public static final String UI_BUTTON_CLICK = "gui.button.press";
@@ -0,0 +1,16 @@
package me.towdium.jecalculation.utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.util.ResourceLocation;
public class ClientUtils {
public static Minecraft mc() {
return Minecraft.getMinecraft();
}
public static void playClickSound(float pitchIn) {
mc().getSoundHandler().playSound(
PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), pitchIn));
}
}
@@ -1,7 +1,7 @@
package me.towdium.jecalculation.utils;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.utils.polyfill.Polyfill;
import me.towdium.jecalculation.polyfill.Polyfill;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -1,476 +1,93 @@
package me.towdium.jecalculation.utils;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.JecaItem;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.utils.wrappers.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.Language;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.*;
import net.minecraftforge.fluids.Fluid;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.BreakIterator;
import java.text.DecimalFormat;
import java.util.*;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static net.minecraft.client.resources.I18n.format;
/**
* Author: Towdium
* Date: 2016/6/25.
*/
@SuppressWarnings("UnusedReturnValue")
@ParametersAreNonnullByDefault
@SuppressWarnings("unused")
public class Utilities {
final static int[] scaleTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE};
static Map<String, String> dictionary = new HashMap<>();
static {
Map<String, ModContainer> modMap = Loader.instance().getIndexedModList();
for (Map.Entry<String, ModContainer> modEntry : modMap.entrySet()) {
String lowercaseId = modEntry.getKey().toLowerCase(Locale.ENGLISH);
String modName = modEntry.getValue().getName();
dictionary.put(lowercaseId, modName);
}
}
// FLOAT FORMATTING
public static char[] suffix = new char[]{'K', 'M', 'B', 'G', 'T', 'P'};
public static DecimalFormat[] format = new DecimalFormat[]{new DecimalFormat("#."),
new DecimalFormat("#.#"),
new DecimalFormat("#.##"),
new DecimalFormat("#.###"),
new DecimalFormat("#.####")};
public static String cutNumber(float f, int size) {
BiFunction<Float, Integer, String> form = (fl, len) -> format[len - 1 - (int) Math.log10(fl)].format(fl);
int scale = (int) Math.log10(f) / 3;
if (scale == 0)
return form.apply(f, size);
else
return form.apply(f / (float) Math.pow(1000, scale), size - 1) + suffix[scale - 1];
}
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public static <T> Stream<T> stream(Optional<T> o) {
return o.map(Stream::of).orElse(Stream.empty());
}
public static <T> Supplier<T> fake(Runnable r) {
return () -> {
r.run();
return null;
public static String cutFloat(float f, int size) {
BiFunction<Float, Integer, String> form = (fl, len) -> {
// here 2 means floating point and unit character
// represents for maximum acceptable decimal digits
int scale = len - 2 - String.valueOf(fl.intValue()).length();
// maximum decimal limits to 2
int cut = Math.min(scale, 2);
return String.format("%." + (Math.max(cut, 0)) + 'f', fl);
};
int scale = (int) Math.log10(f) / 3;
switch (scale) {
case 0:
return form.apply(f, size);
case 1:
return form.apply(f / 1000.0f, size) + 'K';
case 2:
return form.apply(f / 1000000.0f, size) + 'M';
case 3:
return form.apply(f / 1000000000.0f, size) + 'B';
case 4:
return form.apply(f / 1000000000000.0f, size) + 'G';
default:
return form.apply(f / 1000000000000000.0f, size) + 'T';
}
}
public static String repeat(String s, int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++)
sb.append(s);
return sb.toString();
public static String cutLong(long i, int size) {
if (i < 1000) {
return String.valueOf(i);
} else {
return cutFloat(i, size);
}
}
// CIRCULATE STRUCTURE
public static int circulate(int current, int total, boolean forward) {
if (forward) {
if (current == total - 1) return 0;
else return current + 1;
} else {
if (current == 0) return total - 1;
else return current - 1;
}
}
// MOD NAME
@Nullable
public static String getModName(Item item) {
String name = GameData.getItemRegistry().getNameForObject(item);
public static String getModName(ItemStack stack) {
String name = GameData.getItemRegistry().getNameForObject(stack.getItem());
JustEnoughCalculation.logger.warn(String.format("item name: %s", name));
// TODO check
return name;
// ResourceLocation tmp = item.getRegistryName();
// if (tmp == null) return null;
// String id = tmp.getNamespace();
// return id.equals("minecraft") ? "Minecraft" : Loader.instance().getIndexedModList().get(id).getName();
}
public static String getModName(Fluid fluid) {
String name = GameData.getItemRegistry().getNameForObject(fluid);
JustEnoughCalculation.logger.warn(String.format("fluid name: %s", fluid));
public static String getModName(FluidStack stack) {
String name = GameData.getItemRegistry().getNameForObject(stack.getFluid());
JustEnoughCalculation.logger.warn(String.format("fluid name: %s", stack.getFluid()));
// TODO check
return name;
}
public static NBTTagCompound getTag(ItemStack is) {
NBTTagCompound tagCompound = is.getTagCompound();
if (tagCompound == null) {
tagCompound = new NBTTagCompound();
is.setTagCompound(tagCompound);
}
return tagCompound;
// TODO check return is.getOrCreateSubCompound(JustEnoughCalculation.Reference.MODID);
}
public static String translate(String unlocalized, Object... args) {
return net.minecraft.client.resources.I18n.format(unlocalized, args);
}
public static class Relation<K, V> {
public HashMap<Pair<K, K>, V> data = new HashMap<>();
public void put(K a, K b, V v) {
Pair<K, K> pair = new Pair<>(a, b);
V tmp = data.get(pair);
data.put(tmp == null ? new Pair<>(b, a) : pair, v);
}
@Nullable
public V get(K a, K b) {
V ret = data.get(new Pair<>(a, b));
if (ret == null)
ret = data.get(new Pair<>(b, a));
return ret;
}
}
public static class Timer {
long time = System.currentTimeMillis();
boolean running = false;
public void setState(boolean b) {
if (!b && running)
running = false;
if (b && !running) {
running = true;
time = System.currentTimeMillis();
}
}
public long getTime() {
return running ? System.currentTimeMillis() - time : 0;
}
}
@SuppressWarnings("UnusedReturnValue")
public static class Circulator {
int total, current;
public Circulator(int total) {
this(total, 0);
}
public Circulator(int total, int current) {
this.total = total;
this.current = current;
}
public int next() {
return current + 1 == total ? 0 : current + 1;
}
public int prev() {
return current == 0 ? total - 1 : current - 1;
}
public Circulator move(int steps) {
current += steps;
if (current < 0)
current += (-current) / total * total + total;
else
current = current % total;
return this;
}
public int current() {
return current;
}
public Circulator set(int index) {
if (index >= 0 && index < total)
current = index;
else
throw new RuntimeException(String.format("Expected: [0, %d), given: %d.", total, index));
return this;
}
public Circulator copy() {
return new Circulator(total).set(current);
}
}
public static class ReversedIterator<T> implements Iterator<T> {
ListIterator<T> i;
public ReversedIterator(List<T> l) {
i = l.listIterator(l.size());
}
@Override
public boolean hasNext() {
return i.hasPrevious();
}
@Override
public T next() {
return i.previous();
}
public Stream<T> stream() {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, Spliterator.ORDERED), false);
}
}
@Deprecated
@SideOnly(Side.CLIENT)
public static class I18n {
public static boolean contains(String s1, String s2) {
return s1.contains(s2);
}
public static Pair<String, Boolean> search(String translateKey, Object... parameters) {
Pair<String, Boolean> ret = new Pair<>(null, null);
translateKey = "jecalculation." + translateKey;
String buffer = format(translateKey, parameters);
ret.two = !buffer.equals(translateKey);
buffer = StringEscapeUtils.unescapeJava(buffer);
ret.one = buffer.replace("\t", " ");
return ret;
}
public static String get(String translateKey, Object... parameters) {
return search(translateKey, parameters).one;
}
public static List<String> wrap(String s, int width) {
return new TextWrapper().wrap(s, getLocale(), i -> TextWrapper.renderer.getCharWidth(i), width);
}
/**
* Copy from `net.minecraft.client.resources.Language()` 1.12.2
*
* @return Locale
*/
public static Locale getLocale() {
Language language = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage();
String languageCode = language.getLanguageCode();
String[] splitLangCode = languageCode.split("_", 2);
if (splitLangCode.length == 1) { // Vanilla has some languages without underscores
return new Locale(languageCode);
} else {
return new Locale(splitLangCode[0], splitLangCode[1]);
}
}
static class TextWrapper {
static FontRenderer renderer = Minecraft.getMinecraft().fontRenderer;
String str;
BreakIterator it;
List<String> temp = new ArrayList<>();
Function<Character, Integer> func;
int start, end, section, space, cursor, width;
private void cut() {
char c = str.charAt(cursor);
if (c == '\f')
cursor++;
temp.add(str.substring(start, cursor));
if (c == ' ' || c == ' ' || c == '\n')
cursor++;
start = cursor;
end = cursor;
space = width;
section = func.apply(str.charAt(cursor));
}
private void move() {
temp.add(str.substring(start, end));
start = end;
space = width;
}
private List<String> wrap(String s, Locale l, Function<Character, Integer> func, int width) {
temp.clear();
start = 0;
end = 0;
cursor = 0;
space = width;
str = s;
it = BreakIterator.getLineInstance(l);
it.setText(s);
this.width = width;
this.func = func;
for (int i = it.next(); i != BreakIterator.DONE; i = it.next()) {
for (cursor = end; cursor < i; cursor++) {
char ch = str.charAt(cursor);
section += func.apply(str.charAt(cursor));
if (ch == '\n' || ch == '\f')
cut();
else if (section > space) {
if (start == end)
cut();
else
move();
}
}
space -= section;
section = 0;
end = cursor;
}
move();
return temp;
}
}
}
public static class Recent<T> {
LinkedList<T> data = new LinkedList<>();
BiPredicate<T, T> tester;
int limit;
public Recent(BiPredicate<T, T> tester, int limit) {
this.tester = tester;
this.limit = limit;
}
public Recent(int limit) {
this.limit = limit;
}
public boolean push(T obj, boolean replace) {
if (replace)
data.pop();
boolean ret = data.removeIf(t -> tester != null ? tester.test(t, obj) : t.equals(obj));
data.addFirst(obj);
if (data.size() > limit)
data.removeLast();
return ret;
}
public List<T> toList() {
//noinspection unchecked
return (List<T>) data.clone();
}
public void clear() {
data.clear();
}
public int size() {
return data.size();
}
}
public static class Json {
@Nullable
public static NBTTagCompound read(File f) {
try {
String s = FileUtils.readFileToString(f, "UTF-8");
return read(s);
} catch (IOException e) {
return null;
}
}
@Nullable
public static NBTTagCompound read(String s) {
try {
return (NBTTagCompound) JsonToNBT.func_150315_a(s);
} catch (NBTException e) {
e.printStackTrace();
return null;
}
}
public static void write(NBTTagCompound nbt, File f) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
fos.write(write(nbt).getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String write(NBTTagCompound nbt) {
Writer w = new Writer();
write(nbt, w);
w.enter();
return w.build();
}
private static void write(NBTBase nbt, Writer w) {
if (nbt instanceof NBTTagCompound) {
NBTTagCompound tags = (NBTTagCompound) nbt;
boolean wrap = tags.func_150296_c().size() > 1;
boolean first = true;
w.sb.append('{');
if (wrap)
w.indent++;
//noinspection unchecked
for (String i : (Set<String>) tags.func_150296_c()) {
if (first)
first = false;
else
w.sb.append(',');
if (wrap)
w.enter();
w.sb.append('"');
w.sb.append(i);
w.sb.append("\": ");
write(tags.getTag(i), w);
}
if (wrap) {
w.indent--;
w.enter();
}
w.sb.append('}');
} else if (nbt instanceof NBTTagList) {
JustEnoughCalculation.logger.error("nbt is TagList");
// TODO
// NBTTagList tags = (NBTTagList) nbt;
// boolean wrap = tags.tagCount() > 1;
// boolean first = true;
// w.sb.append('[');
// if (wrap) w.indent++;
// for (NBTBase i : tags) {
// if (first) first = false;
// else w.sb.append(',');
// if (wrap) w.enter();
// write(i, w);
// }
// if (wrap) {
// w.indent--;
// w.enter();
// }
// w.sb.append(']');
} else
w.sb.append(nbt.toString());
}
private static class Writer {
public int indent = 0;
StringBuilder sb = new StringBuilder();
public void enter() {
sb.append('\n');
char[] tmp = new char[4 * indent];
Arrays.fill(tmp, ' ');
sb.append(tmp);
}
public String build() {
return sb.toString();
}
}
}
}
@@ -0,0 +1,58 @@
package me.towdium.jecalculation.utils.helpers;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.utils.wrappers.Pair;
import net.minecraft.client.resources.I18n;
import org.apache.commons.lang3.StringEscapeUtils;
/**
* Author: Towdium
* Created: 2016/6/22.
*/
@SideOnly(Side.CLIENT)
public class LocalizationHelper {
public static Pair<String, Boolean> search(String translateKey, Object... parameters) {
Pair<String, Boolean> ret = new Pair<>(null, null);
String buffer = I18n.format(translateKey, parameters);
ret.two = !buffer.equals(translateKey);
buffer = StringEscapeUtils.unescapeJava(buffer);
ret.one = buffer.replace("\t", " ");
return ret;
}
/**
* @param c the (super) class name will be used after prefix translation key
* @param prefix the prefix of translation key
* @param translateKey the body of translation key
* @param parameters format parameters
* @return the localized value
* The localized key is "prefix.className(superClassName).translateKey".
* It will search all the super classes.
*/
public static Pair<String, Boolean> search(Class c, String prefix, String translateKey, Object... parameters) {
StringBuilder builder = new StringBuilder(c.getName());
builder.delete(0, builder.lastIndexOf(".") + 1).setCharAt(0, Character.toLowerCase(builder.charAt(0)));
builder.insert(0, prefix).append('.').append(translateKey); // TODO simplify and change underscore
String key = builder.toString();
Pair<String, Boolean> ret = LocalizationHelper.search(key, parameters);
if (ret.two || c.equals(Object.class))
return ret;
else {
ret = search(c.getSuperclass(), prefix, translateKey, parameters);
if (ret.two)
return ret;
else
return ret.setOne(key);
}
}
public static String format(String translateKey, Object... parameters) {
return search(translateKey, parameters).one;
}
public static String format(Class c, String prefix, String translateKey, Object... parameters) {
return search(c, prefix, translateKey, parameters).one;
}
}
@@ -15,7 +15,7 @@ public class Pair<K, V> {
@Override
public int hashCode() {
return one.hashCode() + two.hashCode();
return one.hashCode() ^ two.hashCode();
}
@Override
@@ -1,45 +1,34 @@
package me.towdium.jecalculation.utils.wrappers;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Author: Towdium
* Date: 2016/7/1.
*/
public class Wrapper<T> {
public class Single<T> {
public T value;
public Predicate<T> predicate = t -> true;
public Wrapper(T value) {
public Single(T value) {
this.value = value;
}
public Wrapper<T> push(@Nullable T value) {
public Single<T> push(@Nullable T value) {
if (value != null && predicate.test(value))
this.value = value;
return this;
}
public Wrapper<T> or(Supplier<T> s) {
if (value == null) value = s.get();
return this;
}
public Optional<T> toOptional() {
return Optional.ofNullable(value);
}
public Wrapper<T> ifPresent(Consumer<T> c) {
public Single<T> ifPresent(Consumer<T> c) {
if (value != null)
c.accept(value);
return this;
}
public Wrapper<T> ifPresentNot(Runnable r) {
public Single<T> ifPresentNot(Runnable r) {
if (value == null)
r.run();
return this;
@@ -4,12 +4,12 @@ package me.towdium.jecalculation.utils.wrappers;
* Author: Towdium
* Date: 2016/7/1.
*/
public class Trio<T, U, V> {
public class Triple<T, U, V> {
public T one;
public U two;
public V three;
public Trio(T one, U two, V three) {
public Triple(T one, U two, V three) {
this.one = one;
this.two = two;
this.three = three;
@@ -1,27 +1,13 @@
gui.calculator.edit=Edit recipes
gui.calculator.add=Add recipe
gui.calculator.output=Output
gui.calculator.procedure=Procedure
gui.calculator.input=Input
gui.calculator.catalyst=Catalyst
gui.calculator.view=All records
gui.calculator.recent=Recent
gui.calculator.editTooltip=Show and edit recorded recipes of selected item
gui.calculator.addTooltip=Add new recipe to the records
gui.calculator.viewTooltip=Show the list of all recorded recipes
gui.calculator.modeTooltip=Switch between:_pInput:_pthe ingredients needed_pProcedure:_psequence of what to craft_pOutput:_pextra output produced_pCatalyst:_presources needed but not consumed
gui.calculator.tooltipUse=Switch between_p#: normal mode_p%: percentage mode_pShift-click for quick change
gui.recipePicker.delete=Delete
gui.recipeEditor.save=Save
gui.recipeEditor.clear=Clear
gui.recipeViewer.edit=Edit
gui.recipeViewer.delete=Delete
item.itemCalculator.name=Calculator
item.item_calculator_crafting.name=Crafting Calculator
item.item_calculator_math.name=Math Calculator
gui.editor.output=Output
gui.editor.catalyst=Cata-\nlyst
gui.editor.input=Input
gui.editor.newGroup=New Group
gui.editor.save=Save
gui.editor.clear=Clear
gui.editor.help=Help
command.not_found=Invalid option: %s
command.unexpected_arg=Unexpected arg: %s
command.help.list=Here is the list of all commands available:
command.state.desc=This mod is working on state: %s
command.state.s_server=server
command.state.s_client=client only
command.state.s_both=client with server
command.state.s_undefined=error state
config.force_client=Force Client
@@ -1,20 +0,0 @@
gui.calculator.edit=编辑记录
gui.calculator.add=添加合成表
gui.calculator.output=产出
gui.calculator.procedure=步骤
gui.calculator.input=材料
gui.calculator.catalyst=催化
gui.calculator.view=浏览记录
gui.calculator.recent=记录
gui.calculator.editTooltip=编辑当前物品的合成表记录
gui.calculator.addTooltip=添加新合成表
gui.calculator.viewTooltip=浏览所有合成表记录
gui.calculator.modeTooltip=在不同模式下切换:_p输入:_p需要的材料_p步骤:_p合成步骤_p产出:_p合成的额外产出_p催化:_p合成时需要但是不被消耗的物品
gui.calculator.tooltipUse=在不同模式下切换_p#: 普通模式_p%: 百分率模式_p按下shift一次改变10
gui.recipePicker.delete=删除
gui.recipeEditor.save=储存
gui.recipeEditor.clear=清除
gui.recipeViewer.edit=编辑
gui.recipeViewer.delete=删除
item.itemCalculator.name=合成计算器
@@ -1,6 +0,0 @@
{
"parent": "builtin/generated",
"textures": {
"layer0": "jecalculation:items/itemCalculator"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "jecalculation:items/item_calculator_crafting"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "jecalculation:items/item_calculator_math"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B