├── .gitignore ├── .gitmodules ├── COMPILING.md ├── LICENSE ├── README.md ├── build.gradle ├── logo.png ├── logo.xcf ├── settings.gradle └── src └── main ├── java └── de │ └── guntram │ └── mcmod │ └── advancementinfo │ ├── AdvancementInfo.java │ ├── AdvancementStep.java │ ├── IteratorReceiver.java │ ├── ModConfig.java │ ├── ModMenuIntegration.java │ ├── accessors │ ├── AdvancementProgressAccessor.java │ ├── AdvancementScreenAccessor.java │ └── AdvancementWidgetAccessor.java │ └── mixin │ ├── AdvancementDisplayMixin.java │ ├── AdvancementProgressMixin.java │ ├── AdvancementScreenMixin.java │ ├── AdvancementTabMixin.java │ ├── AdvancementTabTypeMixin.java │ └── AdvancementWidgetMixin.java └── resources ├── advancementinfo.accesswidener ├── assets └── advancementinfo │ └── lang │ ├── en_us.json │ ├── ja_jp.json │ ├── pt_br.json │ ├── ru_ru.json │ ├── tt_ru.json │ ├── uk_ua.json │ ├── zh_cn.json │ └── zh_tw.json ├── fabric.mod.json ├── icon.png └── mixins.advancementinfo.json /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | build/ 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Versionfiles"] 2 | path = Versionfiles 3 | url = https://github.com/gbl/Versionfiles.git 4 | -------------------------------------------------------------------------------- /COMPILING.md: -------------------------------------------------------------------------------- 1 | # TL;DR 2 | 3 | - Get a version of gradle that's at least 4.10.2 4 | - `git clone ` 5 | - `git branch -r` to see available branches 6 | - `git checkout fabric_1_16` to select your branch 7 | - `git submodule init` 8 | - `git submodule update` 9 | - `/path/to/gradle build` 10 | 11 | # How to compile this mod 12 | 13 | Because I created several mods, which have some things in common, the structure of my mods is a bit different from the example mod that Fabric or Forge provide. 14 | 15 | In particular, I don't want the gradle files to be duplicated into every single mod repository, and some common files that contain version info for Fabric, its tools, and some library mods, have been moved to a (common) submodule. 16 | 17 | # Prerequisites 18 | 19 | You need a gradle installation which does not come with the mod. At the time of this writing, the version of gradle used is 4.10.2. Gradle 6.5 has been tested to work too, so versions between those *should* as well. 20 | 21 | You might already have gradle installed, especially when you're running Linux - if so, make sure it's new enough. For example, Ubuntu 18.04 has gradle 4.4.1 which is not. Run `gradle -version` to check. 22 | 23 | If you have the Fabric example mod installed, you can use the gradle installation from there. Else, download a release from https://gradle.org/releases/ (binary only is sufficient) and unpack it somewhere. 24 | 25 | # Versionfiles submodule 26 | 27 | All my mods use the same repository of files that match MineCraft, Fabric, and common libraries versions. This is included in the mod repository as a Versionfiles submodule, and you should get it when cloning the repo. Run `git submodule init`, then `git submodule update` to get the current version of the files. Do this after selecting your branch, see below. 28 | 29 | # Compiling the mod 30 | 31 | There are branches for the various versions of MineCraft that are supported by the mod. Run `git branch -r` to see which branches there are, then `git checkout branchname` without the `origin/` part, for example, `git checkout fabric_1_16`. 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Guntram Blohm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This mod will enlarge the advancements info UI, so it'll use most of your screen, not just a tiny part of it, especially when your GUI scale is high. 2 | 3 | This means more info visible at the same time, less scrolling, and a better overview. 4 | 5 | Also, it checks out which requirements you've met and which you haven't, and displays a list of those to the right of the UI. This makes it much easier to find what you have done and what you still need to do. 6 | 7 | For example, the "Discover every Biome" Advancement doesn't tell you what's still missing; this mod will help you go for that last biome you haven't visited. 8 | 9 | This works with data pack Advancements as well; here's an example from BlazeAndCave: 10 | 11 | ![Screenshot](https://media.forgecdn.net/attachments/309/457/screenshot_2020-08-22_19-50-58.png "Screenshot") 12 | 13 | If the list to the right overflows, you can use your mouse scroll wheel to scroll. 14 | 15 | ---------------------------------------------------------------------- 16 | 17 | Advancements, and their objectives, have their very own names, which may or may not correspond to MineCraft items, blocks, or entities. The mod tries its best to map those names to Minecraft objects, but in some cases, especially with Data Packs, that's just not possible. The mod will show the internal name in that case in the hope you're better at deciphering what's needed than the mod itself. 18 | 19 | For example, the objective of "The Parrots and the Bats" is named "bred", this will show as bred in the info box. 20 | 21 | 22 | This is the very first version of the mod, and as such, there are probably still bugs. Please report them! 23 | 24 | To make sure the mod doesn't slow down your minecraft, 25 | it has been optimized using 26 | [![JProfiler Logo](https://www.ej-technologies.com/images/product_banners/jprofiler_small.png "Logo")](https://www.ej-technologies.com/products/jprofiler/overview.html). 27 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'fabric-loom' version '1.1-SNAPSHOT' 3 | id "com.modrinth.minotaur" version "2.+" 4 | id "com.matthewprenger.cursegradle" version "1.4.0" 5 | } 6 | 7 | repositories { 8 | maven { 9 | url = "https://maven.fabricmc.net/" 10 | } 11 | maven { 12 | url = "https://minecraft.guntram.de/maven/" 13 | } 14 | maven { 15 | url = "https://maven.terraformersmc.com/releases/" 16 | } 17 | maven { 18 | url = "https://maven.shedaniel.me/" 19 | } 20 | } 21 | 22 | sourceCompatibility = 17 23 | targetCompatibility = 17 24 | 25 | ext.Versions = new Properties() 26 | Versions.load(file("Versionfiles/mcversion-1.19.4.properties").newReader()) 27 | 28 | archivesBaseName = "advancementinfo" 29 | ext.projectVersion = "1.3.1" 30 | 31 | version = "${Versions['minecraft_version']}-fabric${Versions['fabric_versiononly']}-${project.projectVersion}" 32 | 33 | loom { 34 | accessWidenerPath = file("src/main/resources/advancementinfo.accesswidener") 35 | } 36 | 37 | processResources { 38 | inputs.property "version", project.version 39 | 40 | filesMatching("fabric.mod.json") { 41 | expand "version": project.version 42 | } 43 | } 44 | 45 | dependencies { 46 | minecraft "com.mojang:minecraft:${Versions['minecraft_version']}" 47 | mappings "net.fabricmc:yarn:${Versions['yarn_mappings']}:v2" 48 | modImplementation "net.fabricmc:fabric-loader:${Versions['loader_version']}" 49 | modImplementation "net.fabricmc.fabric-api:fabric-api:${Versions['fabric_version']}" 50 | modApi("me.shedaniel.cloth:cloth-config-fabric:${Versions['cloth_config_version']}") { 51 | exclude(group: "net.fabricmc.fabric-api") 52 | } 53 | modCompileOnly "com.terraformersmc:modmenu:${Versions['modmenu_version']}" 54 | } 55 | 56 | java { 57 | withSourcesJar() 58 | } 59 | 60 | jar { 61 | from "LICENSE" 62 | } 63 | 64 | modrinth { 65 | projectId = 'advancementinfo' 66 | versionName = project.archivesBaseName 67 | uploadFile = remapJar 68 | } 69 | 70 | curseforge { 71 | apiKey = System.getenv("CURSEFORGE_TOKEN") ?: "0" 72 | project { 73 | id = '403815' 74 | releaseType = 'release' 75 | addGameVersion("${Versions['minecraft_version']}") 76 | addGameVersion("Java "+targetCompatibility) 77 | addGameVersion("Fabric") 78 | mainArtifact(remapJar) 79 | } 80 | options { 81 | forgeGradleIntegration = false 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbl/AdvancementInfo/075a6f022c934435d0b35b9da60b27f8fdc95cb4/logo.png -------------------------------------------------------------------------------- /logo.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbl/AdvancementInfo/075a6f022c934435d0b35b9da60b27f8fdc95cb4/logo.xcf -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | gradlePluginPortal() 8 | mavenCentral() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/AdvancementInfo.java: -------------------------------------------------------------------------------- 1 | package de.guntram.mcmod.advancementinfo; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementProgressAccessor; 6 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementScreenAccessor; 7 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementWidgetAccessor; 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | import java.util.Collections; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import me.shedaniel.autoconfig.AutoConfig; 15 | import me.shedaniel.autoconfig.ConfigHolder; 16 | import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer; 17 | import net.fabricmc.api.ClientModInitializer; 18 | import net.fabricmc.loader.api.FabricLoader; 19 | import net.minecraft.advancement.Advancement; 20 | import net.minecraft.advancement.AdvancementProgress; 21 | import net.minecraft.advancement.criterion.CriterionConditions; 22 | import net.minecraft.client.gui.screen.advancement.AdvancementTab; 23 | import net.minecraft.client.gui.screen.advancement.AdvancementWidget; 24 | import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; 25 | import net.minecraft.client.network.ClientAdvancementManager; 26 | import net.minecraft.client.resource.language.I18n; 27 | import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer; 28 | import net.minecraft.util.ActionResult; 29 | import org.apache.logging.log4j.Level; 30 | import org.apache.logging.log4j.LogManager; 31 | import org.apache.logging.log4j.Logger; 32 | import org.apache.logging.log4j.core.config.Configurator; 33 | 34 | public class AdvancementInfo implements ClientModInitializer 35 | { 36 | static final String MODID = "advancementinfo"; 37 | static final String VERSION = "@VERSION@"; 38 | static final Logger LOGGER = LogManager.getLogger(); 39 | 40 | static public AdvancementWidget mouseOver, mouseClicked; 41 | static public List cachedClickList; 42 | static public int cachedClickListLineCount; 43 | public static boolean showAll; 44 | public static ModConfig config; 45 | 46 | public static List getSteps(AdvancementWidgetAccessor widget) { 47 | List result = new ArrayList<>(); 48 | addStep(result, widget.getProgress(), widget.getProgress().getUnobtainedCriteria(), false); 49 | addStep(result, widget.getProgress(), widget.getProgress().getObtainedCriteria(), true); 50 | return result; 51 | } 52 | 53 | private static void addStep(List result, AdvancementProgress progress, Iterable criteria, boolean obtained) { 54 | final String[] prefixes = new String[] { "item.minecraft", "block.minecraft", "entity.minecraft", "container", "effect.minecraft", "biome.minecraft" }; 55 | // criteria is actually a List<> .. but play nice 56 | ArrayList sorted = new ArrayList<>(); 57 | for (String s:criteria) { 58 | sorted.add(s); 59 | } 60 | ArrayList details = null; 61 | Collections.sort(sorted); 62 | for (String s: sorted) { 63 | String translation = null; 64 | String key = s; 65 | if (key.startsWith("minecraft:")) { 66 | key=key.substring(10); 67 | } 68 | if (key.startsWith("textures/entity/")) { 69 | String entityAppearance = key.substring(16); 70 | int dotPos; 71 | if ((dotPos = entityAppearance.indexOf("."))>0) { 72 | entityAppearance = entityAppearance.substring(0, dotPos); 73 | } 74 | translation = entityAppearance; 75 | } 76 | if (translation == null) { 77 | for (String prefix: prefixes) { 78 | if (I18n.hasTranslation(prefix+"."+key)) { 79 | translation = I18n.translate(prefix+"."+key); 80 | break; 81 | } 82 | } 83 | } 84 | if (translation == null) { 85 | CriterionConditions conditions = ((AdvancementProgressAccessor)(progress)).getCriterion(s).getConditions(); 86 | if (conditions != null) { 87 | JsonObject o = conditions.toJson(AdvancementEntityPredicateSerializer.INSTANCE); 88 | JsonElement maybeEffects = o.get("effects"); 89 | if (maybeEffects != null && maybeEffects instanceof JsonObject) { 90 | JsonObject effects = (JsonObject) maybeEffects; 91 | details = new ArrayList<>(effects.entrySet().size()); 92 | for (Map.Entry entry: effects.entrySet()) { 93 | details.add(I18n.translate("effect."+entry.getKey().replace(':', '.'))); 94 | } 95 | } 96 | } 97 | translation = key; 98 | } 99 | result.add(new AdvancementStep(translation, obtained, details)); 100 | } 101 | } 102 | 103 | public static void setMatchingFrom(AdvancementsScreen screen, String text) { 104 | List result = new ArrayList<>(); 105 | ClientAdvancementManager advancementHandler = ((AdvancementScreenAccessor)screen).getAdvancementHandler(); 106 | Collection all = advancementHandler.getManager().getAdvancements(); 107 | int lineCount = 0; 108 | 109 | text = text.toLowerCase(); 110 | for (Advancement adv: all) { 111 | if(adv.getId().getPath().startsWith("recipes/")) { 112 | continue; 113 | } 114 | if (adv.getDisplay() == null) { 115 | LOGGER.debug("! {} Has no display", adv.getId()); 116 | continue; 117 | } 118 | if (adv.getDisplay().getTitle() == null) { 119 | LOGGER.debug("! {} Has no title", adv.getId()); 120 | continue; 121 | } 122 | if (adv.getDisplay().getDescription() == null) { 123 | LOGGER.debug("! {} Has no description", adv.getId()); 124 | continue; 125 | } 126 | String title = adv.getDisplay().getTitle().getString(); 127 | String desc = adv.getDisplay().getDescription().getString(); 128 | LOGGER.debug("- {} {}: {} ", adv.getId(), title, desc); 129 | if (title.toLowerCase().contains(text) 130 | || desc.toLowerCase().contains(text)) { 131 | ArrayList details = new ArrayList<>(); 132 | details.add(desc); 133 | AdvancementTab tab = ((AdvancementScreenAccessor)screen).myGetTab(adv); 134 | if (tab == null) { 135 | LOGGER.info("no tab found for advancement {} title {} description {}", adv.getId(), title, desc); 136 | continue; 137 | } 138 | details.add(tab.getTitle().getString()); 139 | boolean done = ((AdvancementWidgetAccessor)(screen.getAdvancementWidget(adv))).getProgress().isDone(); 140 | result.add(new AdvancementStep(title, done, details)); 141 | lineCount+=3; 142 | } 143 | } 144 | cachedClickList = result; 145 | cachedClickListLineCount = lineCount; 146 | mouseOver = null; 147 | } 148 | 149 | @Override 150 | public void onInitializeClient() { 151 | Configurator.setLevel(LOGGER.getName(), Level.ALL); 152 | showAll = false; 153 | if (FabricLoader.getInstance().isModLoaded("cloth-config2")) { 154 | ConfigHolder configHolder = AutoConfig.register(ModConfig.class, JanksonConfigSerializer::new); 155 | configHolder.registerSaveListener((holder, modConfig) -> { 156 | modConfig.validate(); 157 | return ActionResult.PASS; 158 | }); 159 | config = AutoConfig.getConfigHolder(ModConfig.class).getConfig(); 160 | } else { 161 | config = new ModConfig(); 162 | } 163 | 164 | LOGGER.info("AdvancementInfo initialized"); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/AdvancementStep.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo; 7 | 8 | import java.util.List; 9 | 10 | public class AdvancementStep { 11 | 12 | // As we need to run trimToWidth over all entries anyway, which wants 13 | // Strings, not Texts, we can save a few µs by using all Strings here 14 | // and not converting to and fro. 15 | 16 | private String name; 17 | private boolean obtained; 18 | private List details; 19 | 20 | AdvancementStep(String name, boolean obtained, List details) { 21 | this.name = name; 22 | this.obtained = obtained; 23 | this.details = details; 24 | } 25 | 26 | public boolean getObtained() { 27 | return obtained; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public List getDetails() { 35 | return details; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/IteratorReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo; 7 | 8 | /** 9 | * 10 | * @author gbl 11 | */ 12 | public interface IteratorReceiver { 13 | public void accept(int pos, int len); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/ModConfig.java: -------------------------------------------------------------------------------- 1 | package de.guntram.mcmod.advancementinfo; 2 | 3 | import me.shedaniel.autoconfig.ConfigData; 4 | import me.shedaniel.autoconfig.annotation.Config; 5 | import me.shedaniel.autoconfig.annotation.ConfigEntry; 6 | 7 | import static de.guntram.mcmod.advancementinfo.AdvancementInfo.config; 8 | 9 | @Config(name = AdvancementInfo.MODID) 10 | public class ModConfig implements ConfigData { 11 | @ConfigEntry.ColorPicker 12 | public int colorHave = 0x00aa00; 13 | @ConfigEntry.ColorPicker 14 | public int colorHaveNot = 0xaa0000; 15 | public int marginX = 30; 16 | public int marginY = 30; 17 | 18 | @ConfigEntry.Gui.CollapsibleObject 19 | public InfoWidth infoWidth = new InfoWidth(); 20 | 21 | @Override 22 | public void validatePostLoad() throws ValidationException { 23 | ConfigData.super.validatePostLoad(); 24 | this.validate(); 25 | } 26 | 27 | public void validate() { 28 | infoWidth.min = Math.max(100, infoWidth.min); 29 | if (infoWidth.min > infoWidth.max) { 30 | infoWidth.max = infoWidth.min; 31 | } 32 | } 33 | 34 | public static class InfoWidth { 35 | public int min = 120; 36 | public int max = 300; 37 | @ConfigEntry.BoundedDiscrete(min = 0, max = 50) 38 | public int percent = 30; 39 | 40 | private int clamp(int totalWidth) { 41 | int wantWidth = (int) (totalWidth * percent / 100f); 42 | return Math.max(Math.min(wantWidth, max), min); 43 | } 44 | 45 | public int calculate(int screenWidth) { 46 | if (percent == 0 || max == 0) { 47 | return 0; 48 | } 49 | return clamp(screenWidth - config.marginX * 2); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/ModMenuIntegration.java: -------------------------------------------------------------------------------- 1 | package de.guntram.mcmod.advancementinfo; 2 | 3 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 4 | import com.terraformersmc.modmenu.api.ModMenuApi; 5 | import me.shedaniel.autoconfig.AutoConfig; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | 9 | @Environment(EnvType.CLIENT) 10 | public class ModMenuIntegration implements ModMenuApi { 11 | @Override 12 | public ConfigScreenFactory getModConfigScreenFactory() { 13 | return parent -> AutoConfig.getConfigScreen(ModConfig.class, parent).get(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/accessors/AdvancementProgressAccessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.accessors; 7 | 8 | import net.minecraft.advancement.AdvancementCriterion; 9 | 10 | /** 11 | * 12 | * @author gbl 13 | */ 14 | public interface AdvancementProgressAccessor { 15 | public AdvancementCriterion getCriterion(String name); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/accessors/AdvancementScreenAccessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.accessors; 7 | 8 | import net.minecraft.advancement.Advancement; 9 | import net.minecraft.client.gui.screen.advancement.AdvancementTab; 10 | import net.minecraft.client.network.ClientAdvancementManager; 11 | 12 | /** 13 | * 14 | * @author gbl 15 | */ 16 | public interface AdvancementScreenAccessor { 17 | public ClientAdvancementManager getAdvancementHandler(); 18 | public AdvancementTab myGetTab(Advancement advancement); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/accessors/AdvancementWidgetAccessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.accessors; 7 | 8 | import net.minecraft.advancement.AdvancementProgress; 9 | 10 | /** 11 | * 12 | * @author gbl 13 | */ 14 | public interface AdvancementWidgetAccessor { 15 | public AdvancementProgress getProgress(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementDisplayMixin.java: -------------------------------------------------------------------------------- 1 | package de.guntram.mcmod.advancementinfo.mixin; 2 | 3 | import de.guntram.mcmod.advancementinfo.AdvancementInfo; 4 | import net.minecraft.advancement.AdvancementDisplay; 5 | import net.minecraft.text.Text; 6 | import org.spongepowered.asm.mixin.Final; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | 14 | @Mixin(AdvancementDisplay.class) 15 | public class AdvancementDisplayMixin { 16 | 17 | @Shadow @Final private boolean hidden; 18 | @Shadow @Final private Text title; 19 | 20 | @Inject(method="isHidden", at=@At("HEAD"), cancellable = true) 21 | 22 | public void isHiddenOverride(CallbackInfoReturnable cir) { 23 | cir.cancel(); 24 | cir.setReturnValue(hidden && !AdvancementInfo.showAll); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementProgressMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.mixin; 7 | 8 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementProgressAccessor; 9 | import java.util.Map; 10 | import net.minecraft.advancement.AdvancementCriterion; 11 | import net.minecraft.advancement.AdvancementProgress; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.injection.At; 14 | import org.spongepowered.asm.mixin.injection.Inject; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | @Mixin(AdvancementProgress.class) 18 | public class AdvancementProgressMixin implements AdvancementProgressAccessor { 19 | 20 | private Map savedCriteria; 21 | 22 | @Inject(method="init", at=@At("HEAD")) 23 | public void saveCriteria(Map criteria, String[][] requirements, CallbackInfo ci) { 24 | savedCriteria = criteria; 25 | } 26 | 27 | @Override 28 | public AdvancementCriterion getCriterion(String name) { 29 | return savedCriteria.get(name); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementScreenMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.mixin; 7 | 8 | import de.guntram.mcmod.advancementinfo.AdvancementInfo; 9 | import static de.guntram.mcmod.advancementinfo.AdvancementInfo.config; 10 | import de.guntram.mcmod.advancementinfo.AdvancementStep; 11 | import de.guntram.mcmod.advancementinfo.IteratorReceiver; 12 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementScreenAccessor; 13 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementWidgetAccessor; 14 | import java.util.List; 15 | import net.minecraft.advancement.Advancement; 16 | import net.minecraft.client.gui.screen.Screen; 17 | import net.minecraft.client.gui.screen.advancement.AdvancementTab; 18 | import net.minecraft.client.gui.screen.advancement.AdvancementWidget; 19 | import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; 20 | import net.minecraft.client.gui.widget.TextFieldWidget; 21 | import net.minecraft.client.network.ClientAdvancementManager; 22 | import net.minecraft.client.resource.language.I18n; 23 | import net.minecraft.client.util.math.MatrixStack; 24 | import net.minecraft.screen.ScreenTexts; 25 | import org.lwjgl.glfw.GLFW; 26 | import org.spongepowered.asm.mixin.Final; 27 | import org.spongepowered.asm.mixin.Mixin; 28 | import org.spongepowered.asm.mixin.Shadow; 29 | import org.spongepowered.asm.mixin.injection.*; 30 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 31 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 32 | 33 | /** 34 | * 35 | * @author gbl 36 | */ 37 | @Mixin(AdvancementsScreen.class) 38 | public abstract class AdvancementScreenMixin extends Screen implements AdvancementScreenAccessor { 39 | 40 | public AdvancementScreenMixin() { super(null); } 41 | 42 | private int scrollPos; 43 | private int currentInfoWidth = config.infoWidth.calculate(width); 44 | private TextFieldWidget search; 45 | @Shadow @Final private ClientAdvancementManager advancementHandler; 46 | @Shadow protected abstract AdvancementTab getTab(Advancement advancement); 47 | 48 | @ModifyConstant(method="render", constant=@Constant(intValue = 252), require=1) 49 | private int getRenderLeft(int orig) { return width - config.marginX*2; } 50 | 51 | @ModifyConstant(method="render", constant=@Constant(intValue = 140), require=1) 52 | private int getRenderTop(int orig) { return height - config.marginY*2; } 53 | 54 | @ModifyConstant(method="mouseClicked", constant=@Constant(intValue = 252), require=1) 55 | private int getMouseLeft(int orig) { return width - config.marginX*2; } 56 | 57 | @ModifyConstant(method="mouseClicked", constant=@Constant(intValue = 140), require=1) 58 | private int getMouseTop(int orig) { return height - config.marginY*2; } 59 | 60 | @ModifyConstant(method="drawAdvancementTree", constant=@Constant(intValue = 234), require = 1) 61 | private int getAdvTreeXSize(int orig) { return width - config.marginX*2 - 2*9 - currentInfoWidth; } 62 | 63 | @ModifyConstant(method="drawAdvancementTree", constant=@Constant(intValue = 113), require = 1) 64 | private int getAdvTreeYSize(int orig) { return height - config.marginY*2 - 3*9; } 65 | 66 | @Redirect(method = "drawWindow", at=@At(value = "INVOKE", target = "net/minecraft/client/gui/screen/advancement/AdvancementsScreen.drawTexture(Lnet/minecraft/client/util/math/MatrixStack;IIIIII)V")) 67 | public void disableDefaultDraw(MatrixStack matrices, int x, int y, int u, int v, int width, int height) { 68 | // do nothing 69 | } 70 | 71 | @Inject(method="init", at=@At("RETURN")) 72 | private void initSearchField(CallbackInfo ci) { 73 | currentInfoWidth = config.infoWidth.calculate(width); 74 | this.search = new TextFieldWidget(textRenderer, width-config.marginX-currentInfoWidth+9, config.marginY+18, currentInfoWidth-18, 17, ScreenTexts.EMPTY); 75 | } 76 | 77 | @Inject(method="render", 78 | at=@At(value="INVOKE", 79 | target="net/minecraft/client/gui/screen/advancement/AdvancementsScreen.drawWindow(Lnet/minecraft/client/util/math/MatrixStack;II)V")) 80 | public void renderRightFrameBackground(MatrixStack stack, int x, int y, float delta, CallbackInfo ci) { 81 | if(currentInfoWidth == 0) return; 82 | fill(stack, 83 | width-config.marginX-currentInfoWidth+4, config.marginY+4, 84 | width-config.marginX-4, height-config.marginY-4, 0xffc0c0c0); 85 | } 86 | 87 | @Inject(method="drawWindow", 88 | at=@At(value="INVOKE", 89 | target="net/minecraft/client/gui/screen/advancement/AdvancementsScreen.drawTexture(Lnet/minecraft/client/util/math/MatrixStack;IIIIII)V")) 90 | public void renderFrames(MatrixStack stack, int x, int y, CallbackInfo ci) { 91 | int iw = currentInfoWidth; 92 | 93 | int screenW = 252; 94 | int screenH = 140; 95 | // actual size that will be available for the box 96 | int actualW = width - config.marginX - iw - x; 97 | int actualH = width - config.marginY - y; 98 | int halfW = screenW/2; 99 | int halfH = screenH/2; 100 | // When the screen is less than the default size the corners overlap 101 | int clipXh = (int) (Math.max(0, screenW-actualW)/2.+0.5); 102 | int clipXl = (int) (Math.max(0, screenW-actualW)/2.); 103 | int clipYh = (int) (Math.max(0, screenH-actualH)/2.+0.5); 104 | int clipYl = (int) (Math.max(0, screenH-actualH)/2.); 105 | 106 | // The base screen has a resolution of 252x140, divided into 4 quadrants this gives: 107 | // 1 │ 2 x y x y 108 | // ──┼── 1: 0 0 2: 126 0 109 | // 3 │ 4 3: 0 70 4: 126 70 110 | 111 | int rightQuadX = width - config.marginX - halfW - iw + clipXh; 112 | int bottomQuadY = height - config.marginY - halfH + clipYh; 113 | 114 | drawTexture(stack, x, y, 0, 0, halfW-clipXl, halfH-clipYl); // top left 115 | drawTexture(stack, rightQuadX, y, halfW+clipXh, 0, halfW-clipXh, halfH-clipYl); // top right 116 | drawTexture(stack, x, bottomQuadY, 0, halfH+clipYh, halfW-clipXl, halfH-clipYh); // bottom left 117 | drawTexture(stack, rightQuadX, bottomQuadY, halfW+clipXh, halfH+clipYh, halfW-clipXh, halfH-clipYh); // bottom right 118 | 119 | // draw borders 120 | iterate(x+halfW-clipXl, rightQuadX, 200, (pos, len) -> { 121 | drawTexture(stack, pos, y, 15, 0, len, halfH); // top 122 | drawTexture(stack, pos, bottomQuadY, 15, halfH+clipYh, len, halfH-clipYh); // bottom 123 | }); 124 | iterate(y+halfH-clipYl, bottomQuadY, 100, (pos, len) -> { 125 | drawTexture(stack, x, pos, 0, 25, halfW, len); // left 126 | drawTexture(stack, rightQuadX, pos, halfW+clipXh, 25, halfW-clipXh, len); // right 127 | }); 128 | 129 | if(currentInfoWidth == 0) return; 130 | 131 | // draw info corners 132 | int infoWl = (int) (iw/2.); 133 | int infoWh = (int) (iw/2.+0.5); 134 | drawTexture(stack, width-config.marginX - iw , y,0, 0, infoWh, halfH); // 135 | drawTexture(stack, width-config.marginX - infoWl, y, screenW-infoWl, 0, infoWl, halfH); 136 | drawTexture(stack, width-config.marginX - iw , bottomQuadY, 0, halfH, infoWh, halfH); 137 | drawTexture(stack, width-config.marginX - infoWl, bottomQuadY, screenW-infoWl, halfH, infoWl, halfH); 138 | 139 | // draw info borders 140 | // Note: If the info box is too wide there would be missing top & bottom borders 141 | iterate(halfH+config.marginY, bottomQuadY, 100, (pos, len) -> { 142 | drawTexture(stack, width-config.marginX - iw, pos,0, 25, iw/2, len); // left 143 | drawTexture(stack, width-config.marginX - iw/2, pos, screenW-iw/2, 25, iw/2, len); // right 144 | }); 145 | } 146 | 147 | private void iterate(int start, int end, int maxstep, IteratorReceiver func) { 148 | if(start >= end) return; 149 | int size; 150 | for (int i=start; i end) { 153 | size = end - i; 154 | if(size <= 0) return; 155 | } 156 | func.accept(i, size); 157 | } 158 | } 159 | 160 | @Inject(method="drawWindow", at=@At("HEAD")) 161 | public void calculateLayout(MatrixStack matrices, int x, int y, CallbackInfo ci) { 162 | currentInfoWidth = config.infoWidth.calculate(width); 163 | } 164 | 165 | @Inject(method="drawWindow", at=@At("RETURN")) 166 | public void renderRightFrameTitle(MatrixStack stack, int x, int y, CallbackInfo ci) { 167 | if(currentInfoWidth == 0) return; 168 | textRenderer.draw(stack, I18n.translate("advancementinfo.infopane"), width-config.marginX-currentInfoWidth+8, y+6, 4210752); 169 | search.renderButton(stack, x, y, 0); 170 | 171 | if (AdvancementInfo.mouseClicked != null) { 172 | renderCriteria(stack, AdvancementInfo.mouseClicked); 173 | } else if (AdvancementInfo.mouseOver != null || AdvancementInfo.cachedClickList != null) { 174 | renderCriteria(stack, AdvancementInfo.mouseOver); 175 | } 176 | } 177 | 178 | @Inject(method="mouseClicked", at=@At("HEAD"), cancellable = true) 179 | public void rememberClickedWidget(double x, double y, int button, CallbackInfoReturnable cir) { 180 | if (search.mouseClicked(x, y, button)) { 181 | cir.setReturnValue(true); 182 | cir.cancel(); 183 | } 184 | if (x >= width - config.marginX - currentInfoWidth) { 185 | // later: handle click on search results here 186 | return; 187 | } 188 | AdvancementInfo.mouseClicked = AdvancementInfo.mouseOver; 189 | scrollPos = 0; 190 | if (AdvancementInfo.mouseClicked != null) { 191 | AdvancementInfo.cachedClickList = AdvancementInfo.getSteps((AdvancementWidgetAccessor) AdvancementInfo.mouseClicked); 192 | AdvancementInfo.cachedClickListLineCount = AdvancementInfo.cachedClickList.size(); 193 | } else { 194 | AdvancementInfo.cachedClickList = null; 195 | AdvancementInfo.cachedClickListLineCount = 0; 196 | } 197 | } 198 | 199 | @Inject(method="onRootAdded", at=@At("HEAD")) 200 | public void debugRootAdded(Advancement root, CallbackInfo ci) { 201 | // System.out.println("root added to screen; display="+root.getDisplay()+", id="+root.getId().toString()); 202 | } 203 | 204 | // @Inject(method="mouseScrolled", at=@At("HEAD"), cancellable = true) 205 | @Override 206 | public boolean mouseScrolled(double X, double Y, double amount /*, CallbackInfoReturnable cir */) { 207 | if (amount > 0 && scrollPos > 0) { 208 | scrollPos--; 209 | } else if (amount < 0 && AdvancementInfo.cachedClickList != null 210 | && scrollPos < AdvancementInfo.cachedClickListLineCount - ((height-2*config.marginY-45)/textRenderer.fontHeight - 1)) { 211 | scrollPos++; 212 | } 213 | // System.out.println("scrollpos is now "+scrollPos+", needed lines "+AdvancementInfo.cachedClickListLineCount+", shown "+((height-2*config.marginY-45)/textRenderer.fontHeight - 1)); 214 | return false; 215 | } 216 | 217 | @Inject(method="keyPressed", at=@At("HEAD"), cancellable = true) 218 | public void redirectKeysToSearch(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) { 219 | if (search.isActive()) { 220 | if (keyCode == GLFW.GLFW_KEY_ENTER) { 221 | AdvancementInfo.setMatchingFrom((AdvancementsScreen)(Object)this, search.getText()); 222 | } 223 | search.keyPressed(keyCode, scanCode, modifiers); 224 | // Only let ESCAPE end the screen, we don't want the keybind ('L') 225 | // to terminate the screen when we're typing text 226 | if (keyCode != GLFW.GLFW_KEY_ESCAPE) { 227 | cir.setReturnValue(true); 228 | cir.cancel(); 229 | } 230 | } 231 | } 232 | 233 | @Override 234 | public boolean charTyped(char chr, int keyCode) { 235 | if (search.isActive()) { 236 | return search.charTyped(chr, keyCode); 237 | } 238 | return false; 239 | } 240 | 241 | private void renderCriteria(MatrixStack stack, AdvancementWidget widget) { 242 | int y = search.getY() + search.getHeight() + 4; 243 | int skip; 244 | List list; 245 | if (widget == AdvancementInfo.mouseClicked) { 246 | list = AdvancementInfo.cachedClickList; 247 | skip = scrollPos; 248 | } else { 249 | list = AdvancementInfo.getSteps((AdvancementWidgetAccessor) widget); 250 | skip = 0; 251 | } 252 | if (list == null) { 253 | return; 254 | } 255 | for (AdvancementStep entry: list) { 256 | if (skip-- <= 0) { 257 | textRenderer.draw(stack, 258 | textRenderer.trimToWidth(entry.getName(), currentInfoWidth-24), 259 | width-config.marginX-currentInfoWidth+12, y, 260 | entry.getObtained() ? AdvancementInfo.config.colorHave : AdvancementInfo.config.colorHaveNot); 261 | y+=textRenderer.fontHeight; 262 | if (y > height - config.marginY - textRenderer.fontHeight*2) { 263 | return; 264 | } 265 | } 266 | 267 | if (entry.getDetails() != null) { 268 | for (String detail: entry.getDetails()) { 269 | if (skip-- <= 0) { 270 | textRenderer.draw(stack, 271 | textRenderer.trimToWidth(detail, currentInfoWidth-34), 272 | width-config.marginX-currentInfoWidth+22, y, 273 | 0x000000); 274 | y+=textRenderer.fontHeight; 275 | if (y > height - config.marginY - textRenderer.fontHeight*2) { 276 | return; 277 | } 278 | } 279 | } 280 | } 281 | } 282 | } 283 | 284 | @Override 285 | public ClientAdvancementManager getAdvancementHandler() { 286 | return advancementHandler; 287 | } 288 | 289 | public AdvancementTab myGetTab(Advancement advancement) { 290 | return getTab(advancement); 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementTabMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.mixin; 7 | 8 | import de.guntram.mcmod.advancementinfo.AdvancementInfo; 9 | import static de.guntram.mcmod.advancementinfo.AdvancementInfo.config; 10 | import net.minecraft.client.gui.screen.advancement.AdvancementTab; 11 | import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; 12 | import net.minecraft.client.util.math.MatrixStack; 13 | import org.spongepowered.asm.mixin.Final; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Constant; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | 22 | /** 23 | * 24 | * @author gbl 25 | */ 26 | @Mixin(AdvancementTab.class) 27 | public class AdvancementTabMixin { 28 | 29 | @Shadow @Final 30 | private AdvancementsScreen screen; 31 | private int currentInfoWidth; 32 | 33 | @Inject(method="render", at = @At("HEAD")) 34 | private void updateLayout(MatrixStack matrices, int x, int y, CallbackInfo ci) { 35 | if(screen != null) { 36 | currentInfoWidth = config.infoWidth.calculate(screen.width); 37 | } 38 | } 39 | 40 | // space of the whole internal advancements widget 41 | @ModifyConstant(method="render", constant=@Constant(intValue = 234), require = 1) 42 | private int getAdvTreeXSize(int orig) { return screen.width - config.marginX*2 - 2*9 - currentInfoWidth; } 43 | 44 | @ModifyConstant(method="render", constant=@Constant(intValue = 113), require = 1) 45 | private int getAdvTreeYSize(int orig) { return screen.height - config.marginY*2 - 3*9; } 46 | 47 | // origin of the shown tree within the scrollable space 48 | 49 | @ModifyConstant(method="render", constant=@Constant(intValue = 117), require = 1) 50 | private int getAdvTreeXOrig(int orig) { return screen.width/2 - config.marginX - currentInfoWidth/2; } 51 | 52 | @ModifyConstant(method="render", constant=@Constant(intValue = 56), require = 1) 53 | private int getAdvTreeYOrig(int orig) { return screen.height/2 - config.marginY; } 54 | 55 | @ModifyConstant(method="move", constant=@Constant(intValue = 234), require = 2) 56 | private int getMoveXCenter(int orig) { return screen.width - config.marginX*2 - 2*9 - currentInfoWidth; } 57 | 58 | @ModifyConstant(method="move", constant=@Constant(intValue = 113), require = 2) 59 | private int getMoveYCenter(int orig) { return screen.height - config.marginY*2 - 3*9; } 60 | 61 | // need to repeat the texture inside the scrollable space more 62 | 63 | @ModifyConstant(method="render", constant=@Constant(intValue = 15), require = 1) 64 | private int getXTextureRepeats(int orig) { return (screen.width-config.marginX*2 - currentInfoWidth) / 16 + 1; } 65 | 66 | @ModifyConstant(method="render", constant=@Constant(intValue = 8), require = 1) 67 | private int getYTextureRepeats(int orig) { return (screen.height-config.marginY*2) / 16 + 1; } 68 | 69 | // area that can show a tooltip 70 | @ModifyConstant(method="drawWidgetTooltip", constant=@Constant(intValue = 234), require = 2) 71 | private int getTooltipXSize(int orig) { return screen.width - config.marginX*2 - 2*9 - currentInfoWidth; } 72 | 73 | @ModifyConstant(method="drawWidgetTooltip", constant=@Constant(intValue = 113), require = 2) 74 | private int getTooltipYSize(int orig) { return screen.height - config.marginY*2 - 3*9; } 75 | 76 | @Inject(method="drawWidgetTooltip", at=@At("HEAD")) 77 | private void forgetMouseOver(MatrixStack stack, int i, int j, int y, int k, CallbackInfo ci) { 78 | AdvancementInfo.mouseOver = null; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementTabTypeMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.mixin; 7 | 8 | 9 | import de.guntram.mcmod.advancementinfo.AdvancementInfo; 10 | import net.minecraft.client.MinecraftClient; 11 | import net.minecraft.client.gui.screen.advancement.AdvancementTabType; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.injection.Constant; 14 | import org.spongepowered.asm.mixin.injection.ModifyConstant; 15 | 16 | /** 17 | * 18 | * @author gbl 19 | */ 20 | 21 | @Mixin(AdvancementTabType.class) 22 | public class AdvancementTabTypeMixin { 23 | @ModifyConstant(method="getTabX", constant=@Constant(intValue = 248), require = 1) 24 | public int getAdjustedTabX(int orig) { return MinecraftClient.getInstance().currentScreen.width - AdvancementInfo.config.marginX*2 - 4; } 25 | 26 | @ModifyConstant(method="getTabY", constant=@Constant(intValue = 136), require = 1) 27 | public int getAdjustedTabY(int orig) { return MinecraftClient.getInstance().currentScreen.height - AdvancementInfo.config.marginY*2 - 4; } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/guntram/mcmod/advancementinfo/mixin/AdvancementWidgetMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package de.guntram.mcmod.advancementinfo.mixin; 7 | 8 | import de.guntram.mcmod.advancementinfo.AdvancementInfo; 9 | import de.guntram.mcmod.advancementinfo.accessors.AdvancementWidgetAccessor; 10 | import net.minecraft.advancement.AdvancementProgress; 11 | import net.minecraft.client.gui.screen.advancement.AdvancementWidget; 12 | import net.minecraft.client.util.math.MatrixStack; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | import org.spongepowered.asm.mixin.Shadow; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | /** 20 | * 21 | * @author gbl 22 | */ 23 | 24 | @Mixin(AdvancementWidget.class) 25 | public class AdvancementWidgetMixin implements AdvancementWidgetAccessor { 26 | 27 | @Shadow private AdvancementProgress progress; 28 | 29 | @Inject(method="drawTooltip", at=@At("HEAD")) 30 | public void rememberTooltip(MatrixStack stack, int i, int j, float f, int y, int k, CallbackInfo ci) { 31 | AdvancementInfo.mouseOver = (AdvancementWidget)(Object)this; 32 | } 33 | 34 | @Override 35 | public AdvancementProgress getProgress() { 36 | return this.progress; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/resources/advancementinfo.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible class net/minecraft/client/gui/screen/advancement/AdvancementTabType -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "Info", 3 | "text.autoconfig.advancementinfo.title": "AdvancementInfo Settings", 4 | "text.autoconfig.advancementinfo.option.colorHave": "Finished Requirement Color", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "Unfinished Requirement Color", 6 | "text.autoconfig.advancementinfo.option.marginX": "Margin X", 7 | "text.autoconfig.advancementinfo.option.marginY": "Margin Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "Info Width", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "Min", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "Max", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "Percent", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "Enabled", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "Make it easier to see which advancements you have and what's missing.", 15 | "modmenu.descriptionTranslation.advancementinfo": "Make it easier to see which advancements you have and what's missing." 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/ja_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "詳細", 3 | "text.autoconfig.advancementinfo.title": "AdvancementInfo 設定", 4 | "text.autoconfig.advancementinfo.option.colorHave": "達成した条件の色", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "未達成の条件の色", 6 | "text.autoconfig.advancementinfo.option.marginX": "X軸の余白", 7 | "text.autoconfig.advancementinfo.option.marginY": "Y軸の余白", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "詳細表示の幅", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "最小値", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "最大値", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "パーセント", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "有効", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "進捗画面を見やすくし、達成に必要な条件を確認できるようにします。", 15 | "modmenu.descriptionTranslation.advancementinfo": "進捗画面を見やすくし、達成に必要な条件を確認できるようにします。" 16 | } -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/pt_br.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "Info.", 3 | "text.autoconfig.advancementinfo.title": "Configurações do AdvancementInfo", 4 | "text.autoconfig.advancementinfo.option.colorHave": "Cor de Requisitos Finalizados", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "Cor de Requisitos A Fazer", 6 | "text.autoconfig.advancementinfo.option.marginX": "Margem X", 7 | "text.autoconfig.advancementinfo.option.marginY": "Margem Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "Largura da Info.", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "Min", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "Máx", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "Porcento", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "Habilitado", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "Facilita a visualização dos Progressos que você tem e os que ainda faltam.", 15 | "modmenu.descriptionTranslation.advancementinfo": "Facilita a visualização dos Progressos que você tem e os que ainda faltam." 16 | } -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "Информация", 3 | "text.autoconfig.advancementinfo.title": "Настройки AdvancementInfo", 4 | "text.autoconfig.advancementinfo.option.colorHave": "Выполненное требование: цвет", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "Невыполненное требование: цвет", 6 | "text.autoconfig.advancementinfo.option.marginX": "Отступ по X", 7 | "text.autoconfig.advancementinfo.option.marginY": "Отступ по Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "Ширина поля с информацией", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "Минимум", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "Максимум", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "Процент от площади меню", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "Включено", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "Упрощает изучение и выполнение достижений, вы всегда будете знать, что упустили.", 15 | "modmenu.descriptionTranslation.advancementinfo": "Упрощает изучение и выполнение достижений, вы всегда будете знать, что упустили." 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/tt_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "Мәгълүмат", 3 | "text.autoconfig.advancementinfo.title": "AdvancementInfo көйләүләре", 4 | "text.autoconfig.advancementinfo.option.colorHave": "Төгәлләнгән таләп төсе", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "Төгәлләнмәгән таләп төсе", 6 | "text.autoconfig.advancementinfo.option.marginX": "X кыры", 7 | "text.autoconfig.advancementinfo.option.marginY": "Y кыры", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "Мәгълүмат киңлеге", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "Мин", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "Макс", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "Процент", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "Кушык", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "Казанышларның өйрәнүне һәм үтәүне гадиләштерә, үтәлешнең күзәтүне өсти.", 15 | "modmenu.descriptionTranslation.advancementinfo": "Казанышларның өйрәнүне һәм үтәүне гадиләштерә, үтәлешнең күзәтүне өсти." 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/uk_ua.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "Інформація", 3 | "text.autoconfig.advancementinfo.title": "Параметри AdvancementInfo", 4 | "text.autoconfig.advancementinfo.option.colorHave": "Колір виконаної вимоги", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "Колір невиконаної вимоги", 6 | "text.autoconfig.advancementinfo.option.marginX": "Відступ X", 7 | "text.autoconfig.advancementinfo.option.marginY": "Відступ Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "Ширина поля інформації", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "Мін.", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "Макс.", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "Відсотк.", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "Увімк.", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "Спрощує перегляд виконаних та пропущених досягнень.", 15 | "modmenu.descriptionTranslation.advancementinfo": "Спрощує перегляд виконаних та пропущених досягнень." 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "信息", 3 | "text.autoconfig.advancementinfo.title": "进度信息设置", 4 | "text.autoconfig.advancementinfo.option.colorHave": "完成的进度颜色", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "未完成的进度颜色", 6 | "text.autoconfig.advancementinfo.option.marginX": "边距 X", 7 | "text.autoconfig.advancementinfo.option.marginY": "边距 Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "信息宽度", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "最小值", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "最大值", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "百分之", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "启用", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "更轻松地查看您有哪些进度以及缺少哪些进度。", 15 | "modmenu.descriptionTranslation.advancementinfo": "更轻松地查看您有哪些进度以及缺少哪些进度。" 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/advancementinfo/lang/zh_tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "advancementinfo.infopane": "資訊", 3 | "text.autoconfig.advancementinfo.title": "AdvancementInfo 設定", 4 | "text.autoconfig.advancementinfo.option.colorHave": "完成的進度顏色", 5 | "text.autoconfig.advancementinfo.option.colorHaveNot": "未完成的進度顏色", 6 | "text.autoconfig.advancementinfo.option.marginX": "邊距 X", 7 | "text.autoconfig.advancementinfo.option.marginY": "邊距 Y", 8 | "text.autoconfig.advancementinfo.option.infoWidth": "信息寬度", 9 | "text.autoconfig.advancementinfo.option.infoWidth.min": "最小值", 10 | "text.autoconfig.advancementinfo.option.infoWidth.max": "最大值", 11 | "text.autoconfig.advancementinfo.option.infoWidth.percent": "百分之", 12 | "text.autoconfig.advancementinfo.option.infoWidth.enabled": "啟用", 13 | 14 | "modmenu.summaryTranslation.advancementinfo": "可以更輕鬆地查看您擁有哪些進度以及缺少哪些進度。 ", 15 | "modmenu.descriptionTranslation.advancementinfo": "可以更輕鬆地查看您擁有哪些進度以及缺少哪些進度。" 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "advancementinfo", 4 | "version": "${version}", 5 | "environment": "client", 6 | "entrypoints": { 7 | "client": [ "de.guntram.mcmod.advancementinfo.AdvancementInfo" ], 8 | "modmenu": [ "de.guntram.mcmod.advancementinfo.ModMenuIntegration" ] 9 | }, 10 | "custom": { 11 | "modupdater": { 12 | "strategy": "json", 13 | "url": "https://raw.githubusercontent.com/gbl/ModVersionInfo/master/AdvancementInfo.json" 14 | } 15 | }, 16 | "mixins": [ "mixins.advancementinfo.json" ], 17 | "accessWidener": "advancementinfo.accesswidener", 18 | "depends": { 19 | "fabric": "*", 20 | "cloth-config2": ">=5.0.0" 21 | }, 22 | "recommends": { 23 | "modmenu" : ">=2.0.0" 24 | }, 25 | "name": "AdvancementInfo", 26 | "description": "Make it easier to see which advancements you have and what's missing.", 27 | "icon": "icon.png", 28 | "authors": [ "Giselbaer" ], 29 | "contact": { 30 | "homepage": "https://www.curseforge.com/minecraft/mc-mods/advancementinfo", 31 | "sources": "https://github.com/gbl/AdvancementInfo", 32 | "issues": "https://github.com/gbl/AdvancementInfo/issues" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbl/AdvancementInfo/075a6f022c934435d0b35b9da60b27f8fdc95cb4/src/main/resources/icon.png -------------------------------------------------------------------------------- /src/main/resources/mixins.advancementinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "de.guntram.mcmod.advancementinfo.mixin", 4 | "minVersion": "0.6", 5 | "client": [ 6 | "AdvancementScreenMixin", "AdvancementTabMixin", "AdvancementWidgetMixin", 7 | "AdvancementProgressMixin", "AdvancementTabTypeMixin", "AdvancementDisplayMixin" 8 | ], 9 | "injectors": { 10 | "defaultRequire": 1 11 | } 12 | } 13 | --------------------------------------------------------------------------------