|
@@ -1,99 +1,276 @@
|
|
|
package me.hammerle;
|
|
|
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
-import net.minecraft.block.Block;
|
|
|
-import net.minecraft.block.Blocks;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
+import net.minecraft.client.gui.AbstractGui;
|
|
|
+import net.minecraft.client.gui.FontRenderer;
|
|
|
+import net.minecraft.client.util.ITooltipFlag.TooltipFlags;
|
|
|
+import net.minecraft.item.ItemStack;
|
|
|
import net.minecraft.util.text.ChatType;
|
|
|
+import net.minecraft.util.text.ITextComponent;
|
|
|
import net.minecraft.util.text.StringTextComponent;
|
|
|
+import net.minecraftforge.client.event.GuiContainerEvent;
|
|
|
import net.minecraftforge.client.event.ClientChatEvent;
|
|
|
import net.minecraftforge.client.event.ClientChatReceivedEvent;
|
|
|
+import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
|
|
+import net.minecraftforge.event.TickEvent;
|
|
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
|
import net.minecraftforge.fml.common.Mod;
|
|
|
|
|
|
@Mod.EventBusSubscriber
|
|
|
-@Mod("hefix")
|
|
|
+@Mod("hek")
|
|
|
public class HeK {
|
|
|
|
|
|
+ private final static HashMap<String, Skill> SKILLS = new HashMap<>();
|
|
|
+
|
|
|
+ private static void addSkill(String name) {
|
|
|
+ SKILLS.put(name, new Skill(name));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int skillCorner = 0;
|
|
|
+ private static boolean toggle = true;
|
|
|
+
|
|
|
+ static {
|
|
|
+ addSkill("Attack");
|
|
|
+ addSkill("Constitution");
|
|
|
+ addSkill("Mining");
|
|
|
+ addSkill("Smelting");
|
|
|
+ addSkill("Fishing");
|
|
|
+ addSkill("Hunting");
|
|
|
+ addSkill("Taming");
|
|
|
+ addSkill("Leatherworking");
|
|
|
+ addSkill("Tailoring");
|
|
|
+ addSkill("Strength");
|
|
|
+ addSkill("Woodcutting");
|
|
|
+ addSkill("Firemaking");
|
|
|
+ addSkill("Weaponsmithing");
|
|
|
+ addSkill("Farming");
|
|
|
+ addSkill("Cooking");
|
|
|
+ addSkill("Merchanting");
|
|
|
+ addSkill("Crafting");
|
|
|
+ addSkill("Tinkering");
|
|
|
+ addSkill("Ranged");
|
|
|
+ addSkill("Fletching");
|
|
|
+ addSkill("Carpentry");
|
|
|
+ addSkill("Armoursmithing");
|
|
|
+ addSkill("Herblore");
|
|
|
+ addSkill("Agility");
|
|
|
+ addSkill("Thieving");
|
|
|
+ addSkill("Forgery");
|
|
|
+ addSkill("Alchemy");
|
|
|
+ addSkill("Defence");
|
|
|
+
|
|
|
+ load();
|
|
|
+ }
|
|
|
+
|
|
|
private static String filter = "Hegemony";
|
|
|
- private static String percent = null;
|
|
|
- private static double startExp = 0.0;
|
|
|
- private static double exp = 0.0;
|
|
|
- private static double nextExp = 0.0;
|
|
|
|
|
|
private static void sendMessage(String msg) {
|
|
|
Minecraft.getInstance().ingameGUI.addChatMessage(ChatType.CHAT, new StringTextComponent(msg));
|
|
|
}
|
|
|
|
|
|
- private static boolean isOre(Block b) {
|
|
|
- return b == Blocks.IRON_ORE || b == Blocks.COAL_ORE;
|
|
|
+ private static String removeFormatting(ITextComponent text) {
|
|
|
+ return text.getFormattedText().replaceAll("§.", "");
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double parse(String number) {
|
|
|
+ try {
|
|
|
+ return Double.parseDouble(number.replace(",", ""));
|
|
|
+ } catch(NumberFormatException ex) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void save() {
|
|
|
+ File config = new File("./config");
|
|
|
+ if(!config.exists()) {
|
|
|
+ config.mkdir();
|
|
|
+ }
|
|
|
+ ArrayList<String> data = new ArrayList<>();
|
|
|
+ data.add(String.valueOf(skillCorner));
|
|
|
+ try {
|
|
|
+ Files.write(new File("./config/hek").toPath(), data);
|
|
|
+ } catch(IOException ex) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void load() {
|
|
|
+ try {
|
|
|
+ File config = new File("./config/hek");
|
|
|
+ if(!config.exists()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> list = Files.readAllLines(config.toPath());
|
|
|
+ if(list.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ skillCorner = Integer.parseInt(list.get(0));
|
|
|
+ } catch(NumberFormatException ex) {
|
|
|
+ }
|
|
|
+ } catch(Exception ex) {
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@SubscribeEvent
|
|
|
- public static void onClientChat(ClientChatEvent e) {
|
|
|
- if(!e.getMessage().startsWith("/")) {
|
|
|
+ public static void onClientChat(GuiContainerEvent e) {
|
|
|
+ if(!e.getGuiContainer().getTitle().getFormattedText().contains("Skills")) {
|
|
|
return;
|
|
|
}
|
|
|
- String[] parts = e.getMessage().split(" ");
|
|
|
- switch(parts[0]) {
|
|
|
- case "/hefix":
|
|
|
- e.setCanceled(true);
|
|
|
- if(parts.length < 2) {
|
|
|
- filter = null;
|
|
|
- sendMessage("Filter cleared");
|
|
|
- return;
|
|
|
- }
|
|
|
- filter = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
|
|
|
- sendMessage("Filter set to '" + filter + "'");
|
|
|
- break;
|
|
|
- case "/percent":
|
|
|
- e.setCanceled(true);
|
|
|
- if(parts.length < 4) {
|
|
|
- percent = null;
|
|
|
- sendMessage("EXP cleared");
|
|
|
- return;
|
|
|
- }
|
|
|
- percent = parts[1];
|
|
|
- try {
|
|
|
- exp = Double.parseDouble(parts[2]);
|
|
|
- startExp = exp;
|
|
|
- nextExp = Double.parseDouble(parts[3]);
|
|
|
- } catch(NumberFormatException ex) {
|
|
|
- sendMessage("Type valid numbers");
|
|
|
- return;
|
|
|
+ for(ItemStack stack : e.getGuiContainer().getContainer().getInventory()) {
|
|
|
+ if(stack.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String name = removeFormatting(stack.getDisplayName());
|
|
|
+ Skill skill = SKILLS.get(name);
|
|
|
+ if(skill == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<ITextComponent> lore = stack.getTooltip(Minecraft.getInstance().player, TooltipFlags.NORMAL);
|
|
|
+ for(ITextComponent text : lore) {
|
|
|
+ String line = removeFormatting(text);
|
|
|
+ if(line.startsWith("Experience") && line.length() >= 13) {
|
|
|
+ skill.setExperience(parse(line.substring(12)));
|
|
|
}
|
|
|
- sendMessage(String.format("Percent set to '%s' and %.1f and %.1f", percent, exp, nextExp));
|
|
|
- break;
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ @SubscribeEvent
|
|
|
+ public static void onClientChat(ClientChatEvent e) {
|
|
|
+ try {
|
|
|
+ if(!e.getMessage().startsWith("/")) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String[] parts = e.getMessage().split(" ");
|
|
|
+ switch(parts[0]) {
|
|
|
+ case "/hefix":
|
|
|
+ e.setCanceled(true);
|
|
|
+ if(parts.length < 2) {
|
|
|
+ filter = null;
|
|
|
+ sendMessage("Filter cleared");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ filter = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length));
|
|
|
+ sendMessage("Filter set to '" + filter + "'");
|
|
|
+ break;
|
|
|
+ case "/toggle":
|
|
|
+ e.setCanceled(true);
|
|
|
+ skillCorner = (skillCorner + 1) % 4;
|
|
|
+ save();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } catch(Exception ex) {
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@SubscribeEvent
|
|
|
public static void onChatReceive(ClientChatReceivedEvent e) {
|
|
|
- String msg = e.getMessage().getFormattedText();
|
|
|
+ String msg = removeFormatting(e.getMessage());
|
|
|
if(filter != null && msg.contains(filter)) {
|
|
|
e.setCanceled(true);
|
|
|
}
|
|
|
- if(percent != null && e.getType() == ChatType.GAME_INFO && msg.contains(percent)) {
|
|
|
- msg = msg.replaceAll("§.", "");
|
|
|
+ if(e.getType() == ChatType.GAME_INFO) {
|
|
|
String[] parts = msg.split(" ");
|
|
|
- for(int i = 0; i < parts.length; i++) {
|
|
|
- if(parts[i].equals(percent)) {
|
|
|
- if(i == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- try {
|
|
|
- exp += Double.parseDouble(parts[i - 1]);
|
|
|
- double d = ((exp - startExp) * 100.0) / (nextExp - startExp);
|
|
|
- e.setMessage(new StringTextComponent(String.format("§6%s§r +%s - %.1f%%", percent, parts[i - 1], d)));
|
|
|
- return;
|
|
|
- } catch(NumberFormatException ex) {
|
|
|
- e.setMessage(new StringTextComponent(ex.getLocalizedMessage()));
|
|
|
- break;
|
|
|
- }
|
|
|
+ ArrayList<Skill> skills = new ArrayList<>();
|
|
|
+ ArrayList<Double> xp = new ArrayList<>();
|
|
|
+ for(String part : parts) {
|
|
|
+ part = part.replace(",", "");
|
|
|
+ Skill skill = SKILLS.get(part);
|
|
|
+ if(skill != null) {
|
|
|
+ skills.add(skill);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ xp.add(Double.parseDouble(part));
|
|
|
+ } catch(NumberFormatException ex) {
|
|
|
}
|
|
|
}
|
|
|
- e.setCanceled(true);
|
|
|
+ if(skills.size() == xp.size()) {
|
|
|
+ for(int i = 0; i < skills.size(); i++) {
|
|
|
+ skills.get(i).addExperience(xp.get(i));
|
|
|
+ }
|
|
|
+ } else if(xp.size() == 1) {
|
|
|
+ for(int i = 0; i < skills.size(); i++) {
|
|
|
+ skills.get(i).addExperience(xp.get(0));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @SubscribeEvent
|
|
|
+ public static void onClientTick(TickEvent.ClientTickEvent e) {
|
|
|
+ if(e.phase == TickEvent.Phase.END) {
|
|
|
+ SKILLS.values().forEach(skill -> skill.tick());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @SubscribeEvent
|
|
|
+ public static void onRenderGui(RenderGameOverlayEvent.Post e) {
|
|
|
+ if(e.getType() != RenderGameOverlayEvent.ElementType.EXPERIENCE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ toggle = false;
|
|
|
+ List<String> texts = SKILLS.values().stream()
|
|
|
+ .filter(skill -> skill.shouldRender())
|
|
|
+ .sorted()
|
|
|
+ .map(skill -> {
|
|
|
+ String c = "§r";
|
|
|
+ if(toggle) {
|
|
|
+ c = "§7";
|
|
|
+ }
|
|
|
+ toggle = !toggle;
|
|
|
+ if(skill.shouldRenderLastPercent()) {
|
|
|
+ return String.format("§6Lv. %s%d §6%s: %s%.2f%% +%.2f%%",
|
|
|
+ c, skill.getLevel(), skill.getName(), c, skill.getPercent(), skill.getLastPercent());
|
|
|
+ }
|
|
|
+ return String.format("§6Lv. %s%d §6%s: %s%.2f%%",
|
|
|
+ c, skill.getLevel(), skill.getName(), c, skill.getPercent());
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ Minecraft mc = Minecraft.getInstance();
|
|
|
+ FontRenderer fr = mc.fontRenderer;
|
|
|
+ int width = 0;
|
|
|
+ int height = 4;
|
|
|
+ for(String text : texts) {
|
|
|
+ height += fr.FONT_HEIGHT;
|
|
|
+ width = Math.max(fr.getStringWidth(text), width);
|
|
|
+ }
|
|
|
+ width += 4;
|
|
|
+
|
|
|
+ // 0 - top left
|
|
|
+ int y = 0;
|
|
|
+ int x = 0;
|
|
|
+ switch(skillCorner) {
|
|
|
+ case 1: // 1 - top right
|
|
|
+ x = mc.getMainWindow().getScaledWidth() - width;
|
|
|
+ y = 0;
|
|
|
+ break;
|
|
|
+ case 2: // 2 - bottom left
|
|
|
+ x = 0;
|
|
|
+ y = mc.getMainWindow().getScaledHeight() - height;
|
|
|
+ break;
|
|
|
+ case 3: // 3 - bottom right
|
|
|
+ x = mc.getMainWindow().getScaledWidth() - width;
|
|
|
+ y = mc.getMainWindow().getScaledHeight() - height;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ AbstractGui.fill(x, y, x + width, y + height, 1342177280);
|
|
|
+ x += 2;
|
|
|
+ y += 2;
|
|
|
+ for(String text : texts) {
|
|
|
+ fr.drawString(text, x, y, 0xFFFFFF);
|
|
|
+ y += fr.FONT_HEIGHT;
|
|
|
}
|
|
|
}
|
|
|
}
|