This commit is contained in:
		@@ -1,48 +0,0 @@
 | 
			
		||||
package lel.flummi.skilloverlay.api;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
 | 
			
		||||
import lel.flummi.skilloverlay.api.records.Skills;
 | 
			
		||||
import lel.flummi.skilloverlay.api.records.Skills.Skill;
 | 
			
		||||
import lel.flummi.skilloverlay.config.skilloverlayconfig;
 | 
			
		||||
 | 
			
		||||
public class ApiSkills {
 | 
			
		||||
    public static HashMap<String, Skill> SKILLS;
 | 
			
		||||
 | 
			
		||||
    public static void init() {
 | 
			
		||||
        String apikey = skilloverlayconfig.get().general.apiKey;
 | 
			
		||||
        String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey;
 | 
			
		||||
 | 
			
		||||
        if(apikey.length() > 0) {
 | 
			
		||||
            Skills skills = ApiSkills.updateSkills(apiurl);
 | 
			
		||||
            if(skills != null) {
 | 
			
		||||
                SKILLS = skills.skills();
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                System.out.println("leer uff");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Skills updateSkills(String apiurl) {
 | 
			
		||||
        if(apiurl.length() == 0)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            URL url = new URL(apiurl);
 | 
			
		||||
            InputStreamReader reader = new InputStreamReader(url.openStream());
 | 
			
		||||
            Gson gson = new GsonBuilder()
 | 
			
		||||
                    .serializeNulls()
 | 
			
		||||
                    .create();
 | 
			
		||||
            return gson.fromJson(reader, Skills.class);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -4,6 +4,8 @@ import net.minecraft.client.MinecraftClient;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.Timer;
 | 
			
		||||
import java.util.TimerTask;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
@@ -13,39 +15,52 @@ import lel.flummi.skilloverlay.api.records.Profile.Profiles.Member;
 | 
			
		||||
import lel.flummi.skilloverlay.config.skilloverlayconfig;
 | 
			
		||||
 | 
			
		||||
public class PlayerProfile {
 | 
			
		||||
    public static Member PROFILE;
 | 
			
		||||
	public static Member PROFILE;
 | 
			
		||||
	private static Timer timerTask;
 | 
			
		||||
	private static boolean timerSet;
 | 
			
		||||
 | 
			
		||||
    public static void init() {
 | 
			
		||||
        String apikey = skilloverlayconfig.get().general.apiKey;
 | 
			
		||||
        String uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", "");
 | 
			
		||||
        String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid;
 | 
			
		||||
	public static void init(Boolean timer) {
 | 
			
		||||
		if (timer && !timerSet) {
 | 
			
		||||
			timerTask = new Timer("Timer");
 | 
			
		||||
			timerTask.scheduleAtFixedRate(new TimerTask() {
 | 
			
		||||
				public void run() {
 | 
			
		||||
					PlayerProfile.init(false);
 | 
			
		||||
				}
 | 
			
		||||
			}, 1000L, 1000L * 60L);
 | 
			
		||||
			timerSet = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        if(apikey.length() > 0) {
 | 
			
		||||
            Profile profile = PlayerProfile.updateProfile(apiurl);
 | 
			
		||||
            if(profile != null) {
 | 
			
		||||
                profile.profiles().removeIf(p -> !p.selected());
 | 
			
		||||
                PROFILE = profile.profiles().get(0).members().get(uuid);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                System.out.println("leer uff");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		String apikey = skilloverlayconfig.get().general.apiKey;
 | 
			
		||||
		String uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", "");
 | 
			
		||||
		String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid;
 | 
			
		||||
 | 
			
		||||
    public static Profile updateProfile(String apiurl) {
 | 
			
		||||
        if(apiurl.length() == 0)
 | 
			
		||||
            return null;
 | 
			
		||||
		if (apikey.length() > 0) {
 | 
			
		||||
			Profile profile = PlayerProfile.updateProfile(apiurl);
 | 
			
		||||
			if (profile != null) {
 | 
			
		||||
				profile.profiles().removeIf(p -> !p.selected());
 | 
			
		||||
				PROFILE = profile.profiles().get(0).members().get(uuid);
 | 
			
		||||
			} else {
 | 
			
		||||
				System.out.println("leer uff");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            URL url = new URL(apiurl);
 | 
			
		||||
            InputStreamReader reader = new InputStreamReader(url.openStream());
 | 
			
		||||
            Gson gson = new GsonBuilder()
 | 
			
		||||
                    .serializeNulls()
 | 
			
		||||
                    .create();
 | 
			
		||||
            return gson.fromJson(reader, Profile.class);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
		System.out.println("API update! (every minute)");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Profile updateProfile(String apiurl) {
 | 
			
		||||
		if (apiurl.length() == 0)
 | 
			
		||||
			return null;
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
			URL url = new URL(apiurl);
 | 
			
		||||
			InputStreamReader reader = new InputStreamReader(url.openStream());
 | 
			
		||||
			Gson gson = new GsonBuilder()
 | 
			
		||||
					.serializeNulls()
 | 
			
		||||
					.create();
 | 
			
		||||
			return gson.fromJson(reader, Profile.class);
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
package lel.flummi.skilloverlay.api;
 | 
			
		||||
 | 
			
		||||
import java.io.InputStreamReader;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
import com.google.gson.GsonBuilder;
 | 
			
		||||
 | 
			
		||||
import lel.flummi.skilloverlay.api.records.Skills;
 | 
			
		||||
import lel.flummi.skilloverlay.api.records.Skills.Skill;
 | 
			
		||||
import lel.flummi.skilloverlay.config.skilloverlayconfig;
 | 
			
		||||
 | 
			
		||||
public class PlayerSkills {
 | 
			
		||||
	public static HashMap<String, Skill> SKILLS;
 | 
			
		||||
 | 
			
		||||
	public static void init() {
 | 
			
		||||
		String apikey = skilloverlayconfig.get().general.apiKey;
 | 
			
		||||
		String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey;
 | 
			
		||||
 | 
			
		||||
		if (apikey.length() > 0) {
 | 
			
		||||
			Skills skills = PlayerSkills.updateSkills(apiurl);
 | 
			
		||||
			if (skills != null) {
 | 
			
		||||
				SKILLS = skills.skills();
 | 
			
		||||
			} else {
 | 
			
		||||
				System.out.println("leer uff");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static Skills updateSkills(String apiurl) {
 | 
			
		||||
		if (apiurl.length() == 0)
 | 
			
		||||
			return null;
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
			URL url = new URL(apiurl);
 | 
			
		||||
			InputStreamReader reader = new InputStreamReader(url.openStream());
 | 
			
		||||
			Gson gson = new GsonBuilder()
 | 
			
		||||
					.serializeNulls()
 | 
			
		||||
					.create();
 | 
			
		||||
			return gson.fromJson(reader, Skills.class);
 | 
			
		||||
		} catch (Exception e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -6,17 +6,15 @@ import java.util.HashMap;
 | 
			
		||||
import com.google.gson.annotations.SerializedName;
 | 
			
		||||
 | 
			
		||||
public record Profile(
 | 
			
		||||
    boolean success,
 | 
			
		||||
    List<Profiles> profiles
 | 
			
		||||
) {
 | 
			
		||||
    public record Profiles(
 | 
			
		||||
        @SerializedName("profile_id") String profileId,
 | 
			
		||||
        @SerializedName("last_save") long lastSave,
 | 
			
		||||
        HashMap<String, Member> members,
 | 
			
		||||
        boolean selected
 | 
			
		||||
    ) {
 | 
			
		||||
        public record Member(
 | 
			
		||||
            double experience_skill_farming
 | 
			
		||||
        ){}
 | 
			
		||||
    }
 | 
			
		||||
		boolean success,
 | 
			
		||||
		List<Profiles> profiles) {
 | 
			
		||||
	public record Profiles(
 | 
			
		||||
			@SerializedName("profile_id") String profileId,
 | 
			
		||||
			@SerializedName("last_save") long lastSave,
 | 
			
		||||
			HashMap<String, Member> members,
 | 
			
		||||
			boolean selected) {
 | 
			
		||||
		public record Member(
 | 
			
		||||
				float experience_skill_farming) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,31 +3,32 @@ package lel.flummi.skilloverlay.api.records;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import lel.flummi.skilloverlay.utils.SkillInfo;
 | 
			
		||||
 | 
			
		||||
public record Skills(
 | 
			
		||||
    HashMap<String, Skill> skills
 | 
			
		||||
) {
 | 
			
		||||
    public record Skill(
 | 
			
		||||
        String name,
 | 
			
		||||
        int maxLevel,
 | 
			
		||||
        List<Level> levels
 | 
			
		||||
    ) {
 | 
			
		||||
        public record Level(
 | 
			
		||||
            int level,
 | 
			
		||||
            long totalExpRequired
 | 
			
		||||
        ) {}
 | 
			
		||||
		HashMap<String, Skill> skills) {
 | 
			
		||||
	public record Skill(
 | 
			
		||||
			String name,
 | 
			
		||||
			int maxLevel,
 | 
			
		||||
			List<Level> levels) {
 | 
			
		||||
		public record Level(
 | 
			
		||||
				int level,
 | 
			
		||||
				float totalExpRequired) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public int getLevel(double exp) {
 | 
			
		||||
            int aktLevel = 0;
 | 
			
		||||
		public SkillInfo getLevel(float exp) {
 | 
			
		||||
			int aktLevel = 0;
 | 
			
		||||
 | 
			
		||||
            for(Level tmp: this.levels()) {
 | 
			
		||||
                System.out.println((exp > tmp.totalExpRequired) + "; exp: " + exp + "; ter: " + tmp.totalExpRequired);
 | 
			
		||||
                if(exp < tmp.totalExpRequired) {
 | 
			
		||||
                    return aktLevel;
 | 
			
		||||
                }
 | 
			
		||||
                aktLevel = tmp.level;
 | 
			
		||||
            }
 | 
			
		||||
			for (Level tmp : this.levels()) {
 | 
			
		||||
				if (exp < tmp.totalExpRequired) {
 | 
			
		||||
					// int level, float totalXp, float currentXp, float currentXpMax
 | 
			
		||||
					return new SkillInfo(aktLevel, tmp.totalExpRequired, exp, tmp.totalExpRequired);
 | 
			
		||||
				}
 | 
			
		||||
				aktLevel = tmp.level;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,19 +8,19 @@ import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
 | 
			
		||||
 | 
			
		||||
@Config(name = "skilloverlay")
 | 
			
		||||
public class skilloverlayconfig implements ConfigData {
 | 
			
		||||
    @ConfigEntry.Category("general")
 | 
			
		||||
    @ConfigEntry.Gui.TransitiveObject
 | 
			
		||||
    public General general = new General();
 | 
			
		||||
	@ConfigEntry.Category("general")
 | 
			
		||||
	@ConfigEntry.Gui.TransitiveObject
 | 
			
		||||
	public General general = new General();
 | 
			
		||||
 | 
			
		||||
    public static class General {
 | 
			
		||||
        public String apiKey = "";
 | 
			
		||||
    }
 | 
			
		||||
	public static class General {
 | 
			
		||||
		public String apiKey = "";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public static void init() {
 | 
			
		||||
        AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new);
 | 
			
		||||
    }
 | 
			
		||||
	public static void init() {
 | 
			
		||||
		AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public static skilloverlayconfig get() {
 | 
			
		||||
        return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig();
 | 
			
		||||
    }
 | 
			
		||||
	public static skilloverlayconfig get() {
 | 
			
		||||
		return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ import net.fabricmc.api.EnvType;
 | 
			
		||||
import net.fabricmc.api.Environment;
 | 
			
		||||
import net.minecraft.client.gui.hud.InGameHud;
 | 
			
		||||
import net.minecraft.client.util.math.MatrixStack;
 | 
			
		||||
 | 
			
		||||
import org.spongepowered.asm.mixin.Mixin;
 | 
			
		||||
 | 
			
		||||
import org.spongepowered.asm.mixin.Final;
 | 
			
		||||
import org.spongepowered.asm.mixin.Shadow;
 | 
			
		||||
import org.spongepowered.asm.mixin.injection.At;
 | 
			
		||||
@@ -16,10 +18,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 | 
			
		||||
@Environment(EnvType.CLIENT)
 | 
			
		||||
@Mixin(InGameHud.class)
 | 
			
		||||
public abstract class GameRenderMixin {
 | 
			
		||||
    @Shadow @Final private MinecraftClient client;
 | 
			
		||||
	@Shadow
 | 
			
		||||
	@Final
 | 
			
		||||
	private MinecraftClient client;
 | 
			
		||||
 | 
			
		||||
    @Inject(at = @At("RETURN"), method = "render")
 | 
			
		||||
    private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) {
 | 
			
		||||
        skilloverlay.OVERLAY.render(matrices, client);
 | 
			
		||||
    }
 | 
			
		||||
	@Inject(method = "render", at = @At("RETURN"))
 | 
			
		||||
	private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) {
 | 
			
		||||
		skilloverlay.OVERLAY.render(matrices, client);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,10 @@ import net.minecraft.util.Formatting;
 | 
			
		||||
import net.minecraft.client.gui.DrawableHelper;
 | 
			
		||||
import com.mojang.blaze3d.systems.RenderSystem;
 | 
			
		||||
 | 
			
		||||
//import lel.flummi.skilloverlay.skilloverlay;
 | 
			
		||||
import lel.flummi.skilloverlay.api.PlayerProfile;
 | 
			
		||||
import lel.flummi.skilloverlay.api.PlayerSkills;
 | 
			
		||||
import lel.flummi.skilloverlay.utils.LerpUtils;
 | 
			
		||||
import lel.flummi.skilloverlay.utils.SkillInfo;
 | 
			
		||||
import net.fabricmc.api.EnvType;
 | 
			
		||||
import net.fabricmc.api.Environment;
 | 
			
		||||
 | 
			
		||||
@@ -20,256 +22,370 @@ import java.util.LinkedList;
 | 
			
		||||
 | 
			
		||||
@Environment(EnvType.CLIENT)
 | 
			
		||||
public class FarmingOverlay extends DrawableHelper {
 | 
			
		||||
    private MinecraftClient client;
 | 
			
		||||
    private MatrixStack matrixStack;
 | 
			
		||||
	private MinecraftClient client;
 | 
			
		||||
	private MatrixStack matrixStack;
 | 
			
		||||
 | 
			
		||||
    private long lastUpdate = -1;
 | 
			
		||||
    private final LinkedList<Long> counterQueue = new LinkedList<>();
 | 
			
		||||
    private int cultivatingTier = -1;
 | 
			
		||||
    private String cultivatingTierAmount = "1";
 | 
			
		||||
    private long counter = -1;
 | 
			
		||||
    private int cultivating = -1;
 | 
			
		||||
    private int cultivatingLast = -1;
 | 
			
		||||
    private float cropsPerSecondLast = 0;
 | 
			
		||||
    private float cropsPerSecond = 0;
 | 
			
		||||
    private ArrayList<Float> cropsOverLastXSeconds = new ArrayList<>();
 | 
			
		||||
    private String cropName;
 | 
			
		||||
	private long lastUpdate = -1;
 | 
			
		||||
	private final LinkedList<Long> counterQueue = new LinkedList<>();
 | 
			
		||||
	private int cultivatingTier = -1;
 | 
			
		||||
	private String cultivatingTierAmount = "1";
 | 
			
		||||
	private long counter = -1;
 | 
			
		||||
	private int cultivating = -1;
 | 
			
		||||
	private int cultivatingLast = -1;
 | 
			
		||||
	private float cropsPerSecondLast = 0;
 | 
			
		||||
	private float cropsPerSecond = 0;
 | 
			
		||||
	private ArrayList<Float> cropsOverLastXSeconds = new ArrayList<>();
 | 
			
		||||
	private String cropName;
 | 
			
		||||
 | 
			
		||||
    public FarmingOverlay() {
 | 
			
		||||
        /*HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> {
 | 
			
		||||
            if(client.player == null)
 | 
			
		||||
                return;
 | 
			
		||||
            this.render(matrixStack, client);
 | 
			
		||||
        });*/
 | 
			
		||||
    }
 | 
			
		||||
	private SkillInfo skillInfo = null;
 | 
			
		||||
	private SkillInfo skillInfoLast = null;
 | 
			
		||||
	private float lastTotalXp = -1;
 | 
			
		||||
	private boolean isFarming = false;
 | 
			
		||||
	private final LinkedList<Float> xpGainQueue = new LinkedList<>();
 | 
			
		||||
	private float xpGainHourLast = -1;
 | 
			
		||||
	private float xpGainHour = -1;
 | 
			
		||||
	private int xpGainTimer = 0;
 | 
			
		||||
 | 
			
		||||
    public void render(MatrixStack matrixStack, MinecraftClient client) {
 | 
			
		||||
        if (client.player == null)
 | 
			
		||||
            return;
 | 
			
		||||
	public FarmingOverlay() {
 | 
			
		||||
		/*
 | 
			
		||||
		 * HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> {
 | 
			
		||||
		 * if(client.player == null)
 | 
			
		||||
		 * return;
 | 
			
		||||
		 * this.render(matrixStack, client);
 | 
			
		||||
		 * });
 | 
			
		||||
		 */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        this.matrixStack = matrixStack;
 | 
			
		||||
        this.client = MinecraftClient.getInstance();
 | 
			
		||||
	public void render(MatrixStack matrixStack, MinecraftClient client) {
 | 
			
		||||
		if (client.player == null)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
        RenderSystem.enableBlend();
 | 
			
		||||
        this.renderOverlay();
 | 
			
		||||
		this.matrixStack = matrixStack;
 | 
			
		||||
		this.client = MinecraftClient.getInstance();
 | 
			
		||||
 | 
			
		||||
        this.client.getProfiler().pop();
 | 
			
		||||
    }
 | 
			
		||||
		RenderSystem.enableBlend();
 | 
			
		||||
		this.renderOverlay();
 | 
			
		||||
 | 
			
		||||
    public void renderOverlay() {
 | 
			
		||||
        this.lastUpdate = System.currentTimeMillis();
 | 
			
		||||
        ItemStack heldItem = client.player.getMainHandStack();
 | 
			
		||||
        String internalName = "";
 | 
			
		||||
        this.counter = 0;
 | 
			
		||||
        boolean holdingFarmItem = false;
 | 
			
		||||
        this.cultivatingLast = cultivating;
 | 
			
		||||
        this.cultivating = 0;
 | 
			
		||||
		this.client.getProfiler().pop();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
        //System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level());
 | 
			
		||||
	public void renderOverlay() {
 | 
			
		||||
		this.lastUpdate = System.currentTimeMillis();
 | 
			
		||||
		ItemStack heldItem = client.player.getMainHandStack();
 | 
			
		||||
		String internalName = "";
 | 
			
		||||
		this.counter = -1;
 | 
			
		||||
		boolean holdingFarmItem = false;
 | 
			
		||||
		this.cultivatingLast = cultivating;
 | 
			
		||||
		this.cultivating = 0;
 | 
			
		||||
		xpGainHourLast = xpGainHour;
 | 
			
		||||
 | 
			
		||||
        if (heldItem != null) {
 | 
			
		||||
            NbtCompound tag = heldItem.getNbt();
 | 
			
		||||
		// System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level());
 | 
			
		||||
 | 
			
		||||
            if (tag != null && tag.contains("ExtraAttributes", 10)) {
 | 
			
		||||
                NbtCompound ea = tag.getCompound("ExtraAttributes");
 | 
			
		||||
                internalName = ea.getString("id");
 | 
			
		||||
		if (heldItem != null) {
 | 
			
		||||
			NbtCompound tag = heldItem.getNbt();
 | 
			
		||||
 | 
			
		||||
                for (CropType crop : CropType.values()) {
 | 
			
		||||
			if (tag != null && tag.contains("ExtraAttributes", 10)) {
 | 
			
		||||
				NbtCompound ea = tag.getCompound("ExtraAttributes");
 | 
			
		||||
				internalName = ea.getString("id");
 | 
			
		||||
 | 
			
		||||
				for (CropType crop : CropType.values()) {
 | 
			
		||||
					if (internalName.startsWith(crop.toolName)) {
 | 
			
		||||
						this.cropName = crop.item;
 | 
			
		||||
                        holdingFarmItem = true;
 | 
			
		||||
						holdingFarmItem = true;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
                if(holdingFarmItem) {
 | 
			
		||||
                    if (ea.contains("mined_crops", 99)) {
 | 
			
		||||
                        this.counter = ea.getLong("mined_crops");
 | 
			
		||||
                        cultivating = ea.getInt("farmed_cultivating");
 | 
			
		||||
                        this.counterQueue.add(0, this.counter);
 | 
			
		||||
                    } else if (ea.contains("farmed_cultivating", 99)) {
 | 
			
		||||
                        this.counter = ea.getInt("farmed_cultivating");
 | 
			
		||||
                        cultivating = ea.getInt("farmed_cultivating");
 | 
			
		||||
                        this.counterQueue.add(0, this.counter);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    holdingFarmItem = false;
 | 
			
		||||
            }
 | 
			
		||||
				if (holdingFarmItem) {
 | 
			
		||||
					if (ea.contains("mined_crops", 99)) {
 | 
			
		||||
						this.counter = ea.getLong("mined_crops");
 | 
			
		||||
						cultivating = ea.getInt("farmed_cultivating");
 | 
			
		||||
						this.counterQueue.add(0, this.counter);
 | 
			
		||||
					} else if (ea.contains("farmed_cultivating", 99)) {
 | 
			
		||||
						this.counter = ea.getInt("farmed_cultivating");
 | 
			
		||||
						cultivating = ea.getInt("farmed_cultivating");
 | 
			
		||||
						this.counterQueue.add(0, this.counter);
 | 
			
		||||
					}
 | 
			
		||||
				} else
 | 
			
		||||
					holdingFarmItem = false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
            if (this.cultivating < 1000) {
 | 
			
		||||
                this.cultivatingTier = 1;
 | 
			
		||||
                this.cultivatingTierAmount = "1,000";
 | 
			
		||||
            } else if (this.cultivating < 5000) {
 | 
			
		||||
                this.cultivatingTier = 2;
 | 
			
		||||
                this.cultivatingTierAmount = "5,000";
 | 
			
		||||
            } else if (this.cultivating < 25000) {
 | 
			
		||||
                this.cultivatingTier = 3;
 | 
			
		||||
                this.cultivatingTierAmount = "25,000";
 | 
			
		||||
            } else if (this.cultivating < 100000) {
 | 
			
		||||
                this.cultivatingTier = 4;
 | 
			
		||||
                this.cultivatingTierAmount = "100,000";
 | 
			
		||||
            } else if (this.cultivating < 300000) {
 | 
			
		||||
                this.cultivatingTier = 5;
 | 
			
		||||
                this.cultivatingTierAmount = "300,000";
 | 
			
		||||
            } else if (this.cultivating < 1500000) {
 | 
			
		||||
                this.cultivatingTier = 6;
 | 
			
		||||
                this.cultivatingTierAmount = "1,500,000";
 | 
			
		||||
            } else if (this.cultivating < 5000000) {
 | 
			
		||||
                this.cultivatingTier = 7;
 | 
			
		||||
                this.cultivatingTierAmount = "5,000,000";
 | 
			
		||||
            } else if (this.cultivating < 20000000) {
 | 
			
		||||
                this.cultivatingTier = 8;
 | 
			
		||||
                this.cultivatingTierAmount = "20,000,000";
 | 
			
		||||
            } else if (this.cultivating < 100000000) {
 | 
			
		||||
                this.cultivatingTier = 9;
 | 
			
		||||
                this.cultivatingTierAmount = "100,000,000";
 | 
			
		||||
            } else if (this.cultivating > 100000000) {
 | 
			
		||||
                this.cultivatingTier = 10;
 | 
			
		||||
                this.cultivatingTierAmount = "Maxed";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
			if (this.cultivating < 1000) {
 | 
			
		||||
				this.cultivatingTier = 1;
 | 
			
		||||
				this.cultivatingTierAmount = "1,000";
 | 
			
		||||
			} else if (this.cultivating < 5000) {
 | 
			
		||||
				this.cultivatingTier = 2;
 | 
			
		||||
				this.cultivatingTierAmount = "5,000";
 | 
			
		||||
			} else if (this.cultivating < 25000) {
 | 
			
		||||
				this.cultivatingTier = 3;
 | 
			
		||||
				this.cultivatingTierAmount = "25,000";
 | 
			
		||||
			} else if (this.cultivating < 100000) {
 | 
			
		||||
				this.cultivatingTier = 4;
 | 
			
		||||
				this.cultivatingTierAmount = "100,000";
 | 
			
		||||
			} else if (this.cultivating < 300000) {
 | 
			
		||||
				this.cultivatingTier = 5;
 | 
			
		||||
				this.cultivatingTierAmount = "300,000";
 | 
			
		||||
			} else if (this.cultivating < 1500000) {
 | 
			
		||||
				this.cultivatingTier = 6;
 | 
			
		||||
				this.cultivatingTierAmount = "1,500,000";
 | 
			
		||||
			} else if (this.cultivating < 5000000) {
 | 
			
		||||
				this.cultivatingTier = 7;
 | 
			
		||||
				this.cultivatingTierAmount = "5,000,000";
 | 
			
		||||
			} else if (this.cultivating < 20000000) {
 | 
			
		||||
				this.cultivatingTier = 8;
 | 
			
		||||
				this.cultivatingTierAmount = "20,000,000";
 | 
			
		||||
			} else if (this.cultivating < 100000000) {
 | 
			
		||||
				this.cultivatingTier = 9;
 | 
			
		||||
				this.cultivatingTierAmount = "100,000,000";
 | 
			
		||||
			} else if (this.cultivating > 100000000) {
 | 
			
		||||
				this.cultivatingTier = 10;
 | 
			
		||||
				this.cultivatingTierAmount = "Maxed";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        while (this.counterQueue.size() >= 4) {
 | 
			
		||||
            this.counterQueue.removeLast();
 | 
			
		||||
        }
 | 
			
		||||
		skillInfoLast = skillInfo;
 | 
			
		||||
		skillInfo = PlayerSkills.SKILLS.get("FARMING").getLevel(PlayerProfile.PROFILE.experience_skill_farming());
 | 
			
		||||
		if (skillInfo != null) {
 | 
			
		||||
			float totalXp = skillInfo.totalXp;
 | 
			
		||||
			if (lastTotalXp > 0) {
 | 
			
		||||
				float delta = totalXp - lastTotalXp;
 | 
			
		||||
				if (delta > 0 && delta < 1000) {
 | 
			
		||||
					xpGainTimer = 3;
 | 
			
		||||
 | 
			
		||||
        if (this.counterQueue.isEmpty()) {
 | 
			
		||||
            this.cropsPerSecond = -1;
 | 
			
		||||
            this.cropsPerSecondLast = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.cropsPerSecondLast = this.cropsPerSecond;
 | 
			
		||||
            long last = this.counterQueue.getLast();
 | 
			
		||||
            long first = this.counterQueue.getFirst();
 | 
			
		||||
            while (this.cropsOverLastXSeconds.size() > 60) {
 | 
			
		||||
                this.cropsOverLastXSeconds.remove(0);
 | 
			
		||||
            }
 | 
			
		||||
            if ((first - last) / 2f != 0) {
 | 
			
		||||
                this.cropsOverLastXSeconds.add((first - last) / 2f);
 | 
			
		||||
            } else {
 | 
			
		||||
                if (this.cropsPerSecondLast == 0) {
 | 
			
		||||
                    int i = 12;
 | 
			
		||||
                    while (i > 0) {
 | 
			
		||||
                        i--;
 | 
			
		||||
                        if (this.cropsOverLastXSeconds.size() > 0) {
 | 
			
		||||
                            this.cropsOverLastXSeconds.remove(0);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
					xpGainQueue.add(0, delta);
 | 
			
		||||
					while (xpGainQueue.size() > 30) {
 | 
			
		||||
						xpGainQueue.removeLast();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
            if (!holdingFarmItem) {
 | 
			
		||||
                this.cropsOverLastXSeconds.clear();
 | 
			
		||||
                this.cropsPerSecond = -1;
 | 
			
		||||
                this.cropsPerSecondLast = 0;
 | 
			
		||||
            }
 | 
			
		||||
					float totalGain = 0;
 | 
			
		||||
					for (float f : xpGainQueue)
 | 
			
		||||
						totalGain += f;
 | 
			
		||||
 | 
			
		||||
            ArrayList<Float> temp = new ArrayList<>(cropsOverLastXSeconds);
 | 
			
		||||
            if (this.cropsOverLastXSeconds.size() >= 3) {
 | 
			
		||||
                temp.remove(Collections.min(temp));
 | 
			
		||||
            }
 | 
			
		||||
            if (this.cropsOverLastXSeconds.size() >= 6) {
 | 
			
		||||
                temp.remove(Collections.min(temp));
 | 
			
		||||
                temp.remove(Collections.max(temp));
 | 
			
		||||
            }
 | 
			
		||||
            if (this.cropsOverLastXSeconds.size() >= 10) {
 | 
			
		||||
                temp.remove(Collections.max(temp));
 | 
			
		||||
            }
 | 
			
		||||
					xpGainHour = totalGain * (60 * 60) / xpGainQueue.size();
 | 
			
		||||
 | 
			
		||||
            float cropsOverLastXSecondsTotal = 0;
 | 
			
		||||
            for (Float crops : temp) {
 | 
			
		||||
                cropsOverLastXSecondsTotal += crops;
 | 
			
		||||
            }
 | 
			
		||||
            this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0
 | 
			
		||||
                    ? cropsOverLastXSecondsTotal / temp.size()
 | 
			
		||||
                    : 0;
 | 
			
		||||
        }
 | 
			
		||||
					isFarming = true;
 | 
			
		||||
				} else if (xpGainTimer > 0) {
 | 
			
		||||
					xpGainTimer--;
 | 
			
		||||
 | 
			
		||||
        ArrayList<OverlayString> overlayStringList = new ArrayList<>();
 | 
			
		||||
        NumberFormat format = NumberFormat.getIntegerInstance();
 | 
			
		||||
					xpGainQueue.add(0, 0f);
 | 
			
		||||
					while (xpGainQueue.size() > 30) {
 | 
			
		||||
						xpGainQueue.removeLast();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
        // Add all the lines to the array
 | 
			
		||||
        if (this.counter >= 0 && this.cultivating != this.counter) {
 | 
			
		||||
            overlayStringList.add(new OverlayString("Counter", format.format(this.counter)));
 | 
			
		||||
        }
 | 
			
		||||
					float totalGain = 0;
 | 
			
		||||
					for (float f : xpGainQueue)
 | 
			
		||||
						totalGain += f;
 | 
			
		||||
 | 
			
		||||
        if (this.counter >= 0) {
 | 
			
		||||
            if (this.cropsPerSecondLast == this.cropsPerSecond && this.cropsPerSecond <= 0) {
 | 
			
		||||
                overlayStringList.add(new OverlayString(this.cropName + "/m", "N/A"));
 | 
			
		||||
            } else {
 | 
			
		||||
                float cpsInterp = interp(this.cropsPerSecond, this.cropsPerSecondLast);
 | 
			
		||||
                overlayStringList.add(new OverlayString(this.cropName + "/m", String.format("%,.2f", cpsInterp * 60 * 30)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
					xpGainHour = totalGain * (60 * 60) / xpGainQueue.size();
 | 
			
		||||
 | 
			
		||||
        if (this.cultivatingTier <= 9 && this.cultivating > 0) {
 | 
			
		||||
            int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
 | 
			
		||||
            overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount));
 | 
			
		||||
        }
 | 
			
		||||
        if (this.cultivatingTier == 10) {
 | 
			
		||||
            int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
 | 
			
		||||
            overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp)));
 | 
			
		||||
        }
 | 
			
		||||
					isFarming = true;
 | 
			
		||||
				} else if (delta <= 0) {
 | 
			
		||||
					isFarming = false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
        float yaw = client.player.getYaw();
 | 
			
		||||
        float pitch = client.player.getPitch();
 | 
			
		||||
        yaw %= 360;
 | 
			
		||||
        if (yaw < 0)
 | 
			
		||||
            yaw += 360;
 | 
			
		||||
        if (yaw > 180)
 | 
			
		||||
            yaw -= 360;
 | 
			
		||||
        pitch %= 360;
 | 
			
		||||
        if (pitch < 0)
 | 
			
		||||
            pitch += 360;
 | 
			
		||||
        if (pitch > 180)
 | 
			
		||||
            pitch -= 360;
 | 
			
		||||
				lastTotalXp = totalXp;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        overlayStringList.add(new OverlayString("Yaw", String.format("%.2f", yaw) + Formatting.BOLD + "\u1D52"));
 | 
			
		||||
        overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52"));
 | 
			
		||||
		while (this.counterQueue.size() >= 4) {
 | 
			
		||||
			this.counterQueue.removeLast();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        if (!holdingFarmItem) {
 | 
			
		||||
            overlayStringList.clear();
 | 
			
		||||
        }
 | 
			
		||||
		if (this.counterQueue.isEmpty()) {
 | 
			
		||||
			this.cropsPerSecond = -1;
 | 
			
		||||
			this.cropsPerSecondLast = 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			this.cropsPerSecondLast = this.cropsPerSecond;
 | 
			
		||||
			long last = this.counterQueue.getLast();
 | 
			
		||||
			long first = this.counterQueue.getFirst();
 | 
			
		||||
			while (this.cropsOverLastXSeconds.size() > 60) {
 | 
			
		||||
				this.cropsOverLastXSeconds.remove(0);
 | 
			
		||||
			}
 | 
			
		||||
			if ((first - last) / 2f != 0) {
 | 
			
		||||
				this.cropsOverLastXSeconds.add((first - last) / 2f);
 | 
			
		||||
			} else {
 | 
			
		||||
				if (this.cropsPerSecondLast == 0) {
 | 
			
		||||
					int i = 12;
 | 
			
		||||
					while (i > 0) {
 | 
			
		||||
						i--;
 | 
			
		||||
						if (this.cropsOverLastXSeconds.size() > 0) {
 | 
			
		||||
							this.cropsOverLastXSeconds.remove(0);
 | 
			
		||||
						} else {
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
        // Draw HUD
 | 
			
		||||
        int xAxis = 10;
 | 
			
		||||
        int yAxis = 200;
 | 
			
		||||
			if (!holdingFarmItem) {
 | 
			
		||||
				this.cropsOverLastXSeconds.clear();
 | 
			
		||||
				this.cropsPerSecond = -1;
 | 
			
		||||
				this.cropsPerSecondLast = 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
        // Get the longest string in the array
 | 
			
		||||
        int longestString = 0;
 | 
			
		||||
        int BoxWidth = 0;
 | 
			
		||||
        for (OverlayString s : overlayStringList) {
 | 
			
		||||
            String combined = s.toString();
 | 
			
		||||
            if (combined.length() > longestString) {
 | 
			
		||||
                longestString = combined.length();
 | 
			
		||||
                BoxWidth = this.client.textRenderer.getWidth(combined);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
			ArrayList<Float> temp = new ArrayList<>(cropsOverLastXSeconds);
 | 
			
		||||
			if (this.cropsOverLastXSeconds.size() >= 3) {
 | 
			
		||||
				temp.remove(Collections.min(temp));
 | 
			
		||||
			}
 | 
			
		||||
			if (this.cropsOverLastXSeconds.size() >= 6) {
 | 
			
		||||
				temp.remove(Collections.min(temp));
 | 
			
		||||
				temp.remove(Collections.max(temp));
 | 
			
		||||
			}
 | 
			
		||||
			if (this.cropsOverLastXSeconds.size() >= 10) {
 | 
			
		||||
				temp.remove(Collections.max(temp));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
        int lineHeight = this.client.textRenderer.fontHeight + 2;
 | 
			
		||||
			float cropsOverLastXSecondsTotal = 0;
 | 
			
		||||
			for (Float crops : temp) {
 | 
			
		||||
				cropsOverLastXSecondsTotal += crops;
 | 
			
		||||
			}
 | 
			
		||||
			this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0
 | 
			
		||||
					? cropsOverLastXSecondsTotal / temp.size()
 | 
			
		||||
					: 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        DrawableHelper.fill(matrixStack, xAxis, yAxis, xAxis + BoxWidth + 10,
 | 
			
		||||
                yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000);
 | 
			
		||||
		ArrayList<OverlayString> overlayStringList = new ArrayList<>();
 | 
			
		||||
		NumberFormat format = NumberFormat.getIntegerInstance();
 | 
			
		||||
 | 
			
		||||
        for (OverlayString line : overlayStringList) {
 | 
			
		||||
            int offset = 5;
 | 
			
		||||
		// Add all the lines to the array
 | 
			
		||||
		if (this.counter >= 0 && this.cultivating != this.counter) {
 | 
			
		||||
			overlayStringList.add(new OverlayString("Counter", format.format(this.counter)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
            this.client.textRenderer.drawWithShadow(this.matrixStack, line.toString(), xAxis + offset, yAxis + offset, 0xFFFFFF);
 | 
			
		||||
            yAxis += lineHeight;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		if (this.counter >= 0) {
 | 
			
		||||
			if (this.cropsPerSecondLast == this.cropsPerSecond && this.cropsPerSecond <= 0) {
 | 
			
		||||
				overlayStringList.add(new OverlayString(this.cropName + "/m", "N/A"));
 | 
			
		||||
			} else {
 | 
			
		||||
				float cpsInterp = interp(this.cropsPerSecond, this.cropsPerSecondLast);
 | 
			
		||||
				overlayStringList
 | 
			
		||||
						.add(new OverlayString(this.cropName + "/m", String.format("%,.2f", cpsInterp * 60 * 30)));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    private float interp(float now, float last) {
 | 
			
		||||
        float interp = now;
 | 
			
		||||
        if (last >= 0 && last != now) {
 | 
			
		||||
            float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f;
 | 
			
		||||
            factor = LerpUtils.clampZeroOne(factor);
 | 
			
		||||
            interp = last + (now - last) * factor;
 | 
			
		||||
        }
 | 
			
		||||
        return interp;
 | 
			
		||||
    }
 | 
			
		||||
		if (this.cultivatingTier <= 9 && this.cultivating > 0) {
 | 
			
		||||
			int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
 | 
			
		||||
			overlayStringList.add(
 | 
			
		||||
					new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount));
 | 
			
		||||
		}
 | 
			
		||||
		if (this.cultivatingTier == 10) {
 | 
			
		||||
			int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
 | 
			
		||||
			overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    private enum CropType {
 | 
			
		||||
		// xp
 | 
			
		||||
		float xpInterp = xpGainHour;
 | 
			
		||||
		if (xpGainHourLast == xpGainHour && xpGainHour <= 0) {
 | 
			
		||||
			overlayStringList.add(new OverlayString("XP/h", "N/A"));
 | 
			
		||||
		} else {
 | 
			
		||||
			xpInterp = interp(xpGainHour, xpGainHourLast);
 | 
			
		||||
			overlayStringList.add(new OverlayString("XP/h",
 | 
			
		||||
					format.format(xpInterp) + (isFarming ? "" : Formatting.RED + " (PAUSED)")));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// skillinfo
 | 
			
		||||
		if (skillInfo != null && skillInfo.level < 60) {
 | 
			
		||||
			StringBuilder levelStr = new StringBuilder(skillInfo.level);
 | 
			
		||||
			levelStr.append(Formatting.GRAY)
 | 
			
		||||
					.append("[");
 | 
			
		||||
 | 
			
		||||
			float progress = skillInfo.currentXp / skillInfo.currentXpMax;
 | 
			
		||||
			if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) {
 | 
			
		||||
				progress = interp(progress, skillInfoLast.currentXp / skillInfoLast.currentXpMax);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			float lines = 25;
 | 
			
		||||
			for (int i = 0; i < lines; i++) {
 | 
			
		||||
				if (i / lines < progress) {
 | 
			
		||||
					levelStr.append(Formatting.YELLOW);
 | 
			
		||||
				} else {
 | 
			
		||||
					levelStr.append(Formatting.DARK_GRAY);
 | 
			
		||||
				}
 | 
			
		||||
				levelStr.append('|');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			levelStr.append(Formatting.GRAY)
 | 
			
		||||
					.append("] ")
 | 
			
		||||
					.append(Formatting.YELLOW)
 | 
			
		||||
					.append((int) (progress * 100))
 | 
			
		||||
					.append("%");
 | 
			
		||||
 | 
			
		||||
			int current = (int) skillInfo.currentXp;
 | 
			
		||||
			if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) {
 | 
			
		||||
				current = (int) interp(current, skillInfoLast.currentXp);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			int remaining = (int) (skillInfo.currentXpMax - skillInfo.currentXp);
 | 
			
		||||
			if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) {
 | 
			
		||||
				remaining = (int) interp(remaining, (int) (skillInfoLast.currentXpMax - skillInfoLast.currentXp));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			overlayStringList.add(new OverlayString("Farming", levelStr.toString()));
 | 
			
		||||
			overlayStringList.add(new OverlayString("Current XP", format.format(current)));
 | 
			
		||||
 | 
			
		||||
			if (remaining < 0) {
 | 
			
		||||
				overlayStringList.add(new OverlayString("Remaining XP", "Maxed!"));
 | 
			
		||||
				// overlayStringList.add(new OverlayString("ETA", "Maxed!"));
 | 
			
		||||
			} else {
 | 
			
		||||
				overlayStringList.add(new OverlayString("Remaining XP", format.format(remaining)));
 | 
			
		||||
				if (xpGainHour < 1000) {
 | 
			
		||||
					// overlayStringList.add(new OverlayString("ETA", "N/A"));
 | 
			
		||||
				} else {
 | 
			
		||||
					// overlayStringList.add(new OverlayString("ETA", );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		float yaw = client.player.getYaw();
 | 
			
		||||
		float pitch = client.player.getPitch();
 | 
			
		||||
		yaw %= 360;
 | 
			
		||||
		if (yaw < 0)
 | 
			
		||||
			yaw += 360;
 | 
			
		||||
		if (yaw > 180)
 | 
			
		||||
			yaw -= 360;
 | 
			
		||||
		pitch %= 360;
 | 
			
		||||
		if (pitch < 0)
 | 
			
		||||
			pitch += 360;
 | 
			
		||||
		if (pitch > 180)
 | 
			
		||||
			pitch -= 360;
 | 
			
		||||
 | 
			
		||||
		overlayStringList.add(new OverlayString("Yaw", String.format("%.2f", yaw) + Formatting.BOLD + "\u1D52"));
 | 
			
		||||
		overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52"));
 | 
			
		||||
 | 
			
		||||
		if (!holdingFarmItem) {
 | 
			
		||||
			overlayStringList.clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Draw HUD
 | 
			
		||||
		int xAxis = 10;
 | 
			
		||||
		int yAxis = 200;
 | 
			
		||||
 | 
			
		||||
		if (!overlayStringList.isEmpty()) {
 | 
			
		||||
			int BoxWidth = overlayStringList.stream().map(t -> this.client.textRenderer.getWidth(t.toString()))
 | 
			
		||||
					.max(Integer::compareTo).get();
 | 
			
		||||
			int lineHeight = this.client.textRenderer.fontHeight + 2;
 | 
			
		||||
			int offset = 5;
 | 
			
		||||
 | 
			
		||||
			DrawableHelper.fill(matrixStack, xAxis, yAxis, xAxis + BoxWidth + (offset * 2),
 | 
			
		||||
					yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000);
 | 
			
		||||
 | 
			
		||||
			for (OverlayString line : overlayStringList) {
 | 
			
		||||
				this.client.textRenderer.drawWithShadow(this.matrixStack, line.toString(), xAxis + offset,
 | 
			
		||||
						yAxis + offset,
 | 
			
		||||
						0xFFFFFF);
 | 
			
		||||
				yAxis += lineHeight;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private float interp(float now, float last) {
 | 
			
		||||
		float interp = now;
 | 
			
		||||
		if (last >= 0 && last != now) {
 | 
			
		||||
			float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f;
 | 
			
		||||
			factor = LerpUtils.clampZeroOne(factor);
 | 
			
		||||
			interp = last + (now - last) * factor;
 | 
			
		||||
		}
 | 
			
		||||
		return interp;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private enum CropType {
 | 
			
		||||
		WHEAT("THEORETICAL_HOE_WHEAT", "Wheat"),
 | 
			
		||||
		NETHER_WART("THEORETICAL_HOE_WARTS", "Warts"),
 | 
			
		||||
		SUGAR_CANE("THEORETICAL_HOE_CANE", "Sugar"),
 | 
			
		||||
@@ -290,17 +406,17 @@ public class FarmingOverlay extends DrawableHelper {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private class OverlayString {
 | 
			
		||||
        final String type;
 | 
			
		||||
        final String text;
 | 
			
		||||
	private class OverlayString {
 | 
			
		||||
		final String type;
 | 
			
		||||
		final String text;
 | 
			
		||||
 | 
			
		||||
        private OverlayString(String type, String text) {
 | 
			
		||||
            this.type = type;
 | 
			
		||||
            this.text = text;
 | 
			
		||||
        }
 | 
			
		||||
		private OverlayString(String type, String text) {
 | 
			
		||||
			this.type = type;
 | 
			
		||||
			this.text = text;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public String toString() {
 | 
			
		||||
            return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		public String toString() {
 | 
			
		||||
			return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,33 @@
 | 
			
		||||
package lel.flummi.skilloverlay;
 | 
			
		||||
 | 
			
		||||
import net.fabricmc.api.ModInitializer;
 | 
			
		||||
 | 
			
		||||
//import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
 | 
			
		||||
import lel.flummi.skilloverlay.overlays.FarmingOverlay;
 | 
			
		||||
 | 
			
		||||
import lel.flummi.skilloverlay.api.PlayerProfile;
 | 
			
		||||
import lel.flummi.skilloverlay.api.ApiSkills;
 | 
			
		||||
import lel.flummi.skilloverlay.config.skilloverlayconfig; 
 | 
			
		||||
import lel.flummi.skilloverlay.api.PlayerSkills;
 | 
			
		||||
import lel.flummi.skilloverlay.config.skilloverlayconfig;
 | 
			
		||||
 | 
			
		||||
public class skilloverlay implements ModInitializer {
 | 
			
		||||
    public static FarmingOverlay OVERLAY;
 | 
			
		||||
    public static PlayerProfile API;
 | 
			
		||||
	public static FarmingOverlay OVERLAY;
 | 
			
		||||
	public static PlayerProfile API;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onInitialize() {
 | 
			
		||||
        System.out.println("Skilloverlay started.");
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onInitialize() {
 | 
			
		||||
		System.out.println("Skilloverlay started.");
 | 
			
		||||
 | 
			
		||||
        skilloverlayconfig.init();
 | 
			
		||||
        OVERLAY = new FarmingOverlay();
 | 
			
		||||
		skilloverlayconfig.init();
 | 
			
		||||
		OVERLAY = new FarmingOverlay();
 | 
			
		||||
 | 
			
		||||
        ApiSkills.init();
 | 
			
		||||
        PlayerProfile.init();
 | 
			
		||||
    }
 | 
			
		||||
		PlayerSkills.init();
 | 
			
		||||
		PlayerProfile.init(false);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> {
 | 
			
		||||
		 * System.out.println("message: " + message.getContent() + "; overlay: " +
 | 
			
		||||
		 * overlay);
 | 
			
		||||
		 * return true;
 | 
			
		||||
		 * });
 | 
			
		||||
		 */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,24 @@
 | 
			
		||||
package lel.flummi.skilloverlay.utils;
 | 
			
		||||
 | 
			
		||||
public class LerpUtils {
 | 
			
		||||
    public static float clampZeroOne(float f) {
 | 
			
		||||
        return Math.max(0, Math.min(1, f));
 | 
			
		||||
    }
 | 
			
		||||
	public static float clampZeroOne(float f) {
 | 
			
		||||
		return Math.max(0, Math.min(1, f));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public static float sigmoid(float val) {
 | 
			
		||||
        return (float) (1 / (1 + Math.exp(-val)));
 | 
			
		||||
    }
 | 
			
		||||
	public static float sigmoid(float val) {
 | 
			
		||||
		return (float) (1 / (1 + Math.exp(-val)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private static final float sigmoidStr = 8;
 | 
			
		||||
    private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr));
 | 
			
		||||
    private static final float sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr);
 | 
			
		||||
	private static final float sigmoidStr = 8;
 | 
			
		||||
	private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr));
 | 
			
		||||
	private static final float sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr);
 | 
			
		||||
 | 
			
		||||
    public static float sigmoidZeroOne(float f) {
 | 
			
		||||
        f = clampZeroOne(f);
 | 
			
		||||
        return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB;
 | 
			
		||||
    }
 | 
			
		||||
	public static float sigmoidZeroOne(float f) {
 | 
			
		||||
		f = clampZeroOne(f);
 | 
			
		||||
		return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public static float lerp(float a, float b, float amount) {
 | 
			
		||||
        return b + (a - b) * clampZeroOne(amount);
 | 
			
		||||
    }
 | 
			
		||||
	public static float lerp(float a, float b, float amount) {
 | 
			
		||||
		return b + (a - b) * clampZeroOne(amount);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
package lel.flummi.skilloverlay.utils;
 | 
			
		||||
 | 
			
		||||
public class SkillInfo {
 | 
			
		||||
	public final int level;
 | 
			
		||||
	public final float totalXp;
 | 
			
		||||
	public final float currentXp;
 | 
			
		||||
	public final float currentXpMax;
 | 
			
		||||
	public boolean fromApi = true;
 | 
			
		||||
 | 
			
		||||
	public SkillInfo(int level, float totalXp, float currentXp, float currentXpMax) {
 | 
			
		||||
		this.level = level;
 | 
			
		||||
		this.totalXp = totalXp;
 | 
			
		||||
		this.currentXp = currentXp;
 | 
			
		||||
		this.currentXpMax = currentXpMax;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
package lel.flummi.skilloverlay.utils;
 | 
			
		||||
 | 
			
		||||
public class XPInformation {
 | 
			
		||||
	private static final XPInformation INSTANCE = new XPInformation();
 | 
			
		||||
 | 
			
		||||
	public static XPInformation getInstance() {
 | 
			
		||||
		return INSTANCE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class SkillInfo {
 | 
			
		||||
		public int level;
 | 
			
		||||
		public float totalXp;
 | 
			
		||||
		public float currentXp;
 | 
			
		||||
		public float currentXpMax;
 | 
			
		||||
		public boolean fromApi = false;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user