From 2692193e54e4dd6c0117dcdb85368dc83bb04f1a Mon Sep 17 00:00:00 2001 From: Roman / Nea Date: Mon, 18 Apr 2022 17:33:32 +0200 Subject: Mob loot recipe PR (#81) * entity renderer (somewhat functionaL) * more modifiers and entities * Fix cookie fuckup * add neu repo as resource pack, cause why not at this point * add tabs, because i can * add extra skin parts and make less tabs * hot tall men * fix texture offsets and also parts:true * some untested changes * still broken, but better (just like me (stop being edgy nea ( no u )))) * stuff (with er skeletons * niceities * skytils interop * horseys * horseys ouch * panos * stupid tests :angery: * NPE * add drop chance * colored leather armo * finish off * move shit into hover cause items look pretty terrible * Update 2.1.md * better recipe display name * always show mobs toggle * moving parts --- .../moulberry/notenoughupdates/NEUManager.java | 18 +- .../moulberry/notenoughupdates/NEUOverlay.java | 2 +- .../notenoughupdates/NEURepoResourcePack.java | 75 ++++ .../notenoughupdates/NotEnoughUpdates.java | 9 + .../commands/EntityViewerCommand.java | 81 ++++ .../commands/dev/DevTestCommand.java | 2 +- .../miscfeatures/entityviewer/AgeModifier.java | 30 ++ .../miscfeatures/entityviewer/ChargedModifier.java | 17 + .../miscfeatures/entityviewer/EntityViewer.java | 177 +++++++++ .../entityviewer/EntityViewerModifier.java | 8 + .../entityviewer/EquipmentModifier.java | 72 ++++ .../miscfeatures/entityviewer/GUIClientPlayer.java | 40 ++ .../miscfeatures/entityviewer/HorseModifier.java | 66 +++ .../entityviewer/InvisibleModifier.java | 12 + .../miscfeatures/entityviewer/RidingModifier.java | 14 + .../miscfeatures/entityviewer/SkinModifier.java | 46 +++ .../miscfeatures/entityviewer/WitherModifier.java | 29 ++ .../notenoughupdates/miscgui/GuiItemRecipe.java | 199 +++++++--- .../mixins/AccessorEntityAgeable.java | 12 + .../mixins/AccessorEntityArmorStand.java | 12 + .../notenoughupdates/mixins/AccessorMinecraft.java | 14 + .../mixins/MixinEntityAgeable.java | 1 + .../notenoughupdates/mixins/MixinEntityHorse.java | 17 + .../mixins/MixinEntitySkeleton.java | 17 + .../notenoughupdates/options/NEUConfig.java | 4 + .../options/seperateSections/Itemlist.java | 10 + .../profileviewer/GuiProfileViewer.java | 36 +- .../notenoughupdates/profileviewer/Panorama.java | 38 ++ .../notenoughupdates/recipes/CraftingOverlay.java | 2 +- .../notenoughupdates/recipes/CraftingRecipe.java | 257 ++++++------ .../notenoughupdates/recipes/ForgeRecipe.java | 442 ++++++++++----------- .../notenoughupdates/recipes/Ingredient.java | 5 +- .../notenoughupdates/recipes/MobLootRecipe.java | 309 ++++++++++++++ .../notenoughupdates/recipes/NeuRecipe.java | 24 +- .../notenoughupdates/recipes/RecipeGenerator.java | 169 +++++++- .../notenoughupdates/recipes/RecipeType.java | 59 +++ .../recipes/VillagerTradeRecipe.java | 256 ++++++------ .../moulberry/notenoughupdates/util/ItemUtils.java | 33 ++ .../moulberry/notenoughupdates/util/JsonUtils.java | 42 ++ .../notenoughupdates/util/SkytilsCompat.java | 82 ++++ .../moulberry/notenoughupdates/util/Utils.java | 17 +- 41 files changed, 2143 insertions(+), 612 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/AgeModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/ChargedModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewerModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EquipmentModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/HorseModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/InvisibleModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/RidingModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/SkinModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/WitherModifier.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityAgeable.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityArmorStand.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorMinecraft.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityHorse.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntitySkeleton.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/JsonUtils.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/SkytilsCompat.java (limited to 'src/main/java/io') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index abe0bdcf..6572431b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -895,12 +895,12 @@ public class NEUManager { String clickcommand = item.get("clickcommand").getAsString(); switch (clickcommand.intern()) { case "viewrecipe": - displayGuiItemRecipe(internalName, null); + displayGuiItemRecipe(internalName); break; case "viewoption": neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT)); } - displayGuiItemRecipe(internalName, ""); + displayGuiItemRecipe(internalName); } public void showRecipe(String internalName) { @@ -990,16 +990,16 @@ public class NEUManager { List usages = getAvailableUsagesFor(internalName); if (usages.isEmpty()) return false; Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe("Item Usages", usages, this)); + new GuiItemRecipe(usages, this)); return true; } - public boolean displayGuiItemRecipe(String internalName, String text) { + public boolean displayGuiItemRecipe(String internalName) { if (!recipesMap.containsKey(internalName)) return false; List recipes = getAvailableRecipesFor(internalName); if (recipes.isEmpty()) return false; Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe(text != null ? text : "Item Recipe", recipes, this)); + new GuiItemRecipe(recipes, this)); return true; } @@ -1010,7 +1010,7 @@ public class NEUManager { public boolean failViewItem(String text) { if (viewItemAttemptID != null && !viewItemAttemptID.isEmpty()) { if (System.currentTimeMillis() - viewItemAttemptTime < 500) { - return displayGuiItemRecipe(viewItemAttemptID, text); + return displayGuiItemRecipe(viewItemAttemptID); } } return false; @@ -1570,4 +1570,10 @@ public class NEUManager { } } } + + public ItemStack createItem(String internalname) { + JsonObject jsonObject = itemMap.get(internalname); + if (jsonObject == null) return null; + return jsonToStack(jsonObject); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 7965abae..8d0955bb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1358,7 +1358,7 @@ public class NEUOverlay extends Gui { } if (getSortMode() == SORT_MODE_ALL) { - return !internalname.matches(mobRegex); + return NotEnoughUpdates.INSTANCE.config.itemlist.alwaysShowMonsters || !internalname.matches(mobRegex); } else if (getSortMode() == SORT_MODE_MOB) { return internalname.matches(mobRegex); } else if (getSortMode() == SORT_MODE_PET) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java b/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java new file mode 100644 index 00000000..2a5cda92 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java @@ -0,0 +1,75 @@ +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonObject; +import net.minecraft.client.resources.IResourcePack; +import net.minecraft.client.resources.data.IMetadataSection; +import net.minecraft.client.resources.data.IMetadataSerializer; +import net.minecraft.util.ResourceLocation; + +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.HashSet; +import java.util.Set; + +public class NEURepoResourcePack implements IResourcePack { + + File repoLocation; + Set resourceDomains = new HashSet<>(); + + public NEURepoResourcePack(File repoLocation, String domain) { + this.repoLocation = repoLocation; + resourceDomains.add(domain); + } + + public boolean loadRepoLocation() { + if (repoLocation != null) return true; + NotEnoughUpdates instance = NotEnoughUpdates.INSTANCE; + if (instance == null) return false; + NEUManager manager = instance.manager; + if (manager == null) return false; + repoLocation = manager.repoLocation; + return repoLocation != null; + } + + public File getFileForResource(ResourceLocation loc) { + if (repoLocation == null) { + if (!loadRepoLocation()) + return null; + } + if (!"neurepo".equals(loc.getResourceDomain())) { + return null; + } + return new File(repoLocation, loc.getResourcePath()); + } + + @Override + public InputStream getInputStream(ResourceLocation resourceLocation) throws IOException { + return new BufferedInputStream(new FileInputStream(getFileForResource(resourceLocation))); + } + + @Override + public boolean resourceExists(ResourceLocation resourceLocation) { + File file = getFileForResource(resourceLocation); + return file != null && file.exists(); + } + + @Override + public Set getResourceDomains() { + return resourceDomains; + } + + @Override + public T getPackMetadata(IMetadataSerializer iMetadataSerializer, String s) throws IOException { + return iMetadataSerializer.parseMetadataSection(s, new JsonObject()); + } + + @Override + public BufferedImage getPackImage() throws IOException { + return null; + } + + @Override + public String getPackName() { + return "NEU Repo Resources"; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 0a77c677..6b2fd09e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -35,6 +35,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.Custom import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures; import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import io.github.moulberry.notenoughupdates.mixins.AccessorMinecraft; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.FuelBar; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; @@ -58,6 +59,7 @@ import net.minecraft.world.biome.BiomeGenJungle; import net.minecraft.world.biome.BiomeGenMesa; import net.minecraft.world.biome.BiomeGenSnow; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; @@ -160,6 +162,13 @@ public class NotEnoughUpdates { return this.neuDir; } + public NotEnoughUpdates() { + // Budget Construction Event + ((AccessorMinecraft) FMLClientHandler.instance().getClient()) + .onGetDefaultResourcePacks() + .add(new NEURepoResourcePack(null, "neurepo")); + } + /** * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder. */ diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java new file mode 100644 index 00000000..c7b1862e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java @@ -0,0 +1,81 @@ +package io.github.moulberry.notenoughupdates.commands; + +import com.google.common.collect.Lists; +import io.github.moulberry.notenoughupdates.miscfeatures.entityviewer.EntityViewer; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.event.ClickEvent; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.Arrays; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedDeque; + +public class EntityViewerCommand extends ClientCommandBase { + public EntityViewerCommand() { + super("neushowentity"); + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + public List getCommandAliases() { + return Lists.newArrayList("neuentityviewer"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return EnumChatFormatting.RED + "Use /neushowentity list"; + } + + public void showUsage(ICommandSender sender) { + sender.addChatMessage(new ChatComponentText(getCommandUsage(sender))); + } + + private final Queue queuedGUIS = new ConcurrentLinkedDeque<>(); + + @SubscribeEvent + public void onTick(TickEvent event) { + if (Minecraft.getMinecraft().currentScreen == null) { + EntityViewer poll = queuedGUIS.poll(); + if (poll == null) return; + Minecraft.getMinecraft().displayGuiScreen(poll); + } + } + + @Override + public void processCommand(ICommandSender sender, String[] strings) throws CommandException { + if (strings.length == 0) { + showUsage(sender); + return; + } + if (strings[0].equals("list")) { + for (String label : EntityViewer.validEntities.keySet()) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.BLUE + " " + label) + .setChatStyle(new ChatStyle().setChatClickEvent( + new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/neuentityviewer " + label)))); + } + return; + } + EntityLivingBase entityLivingBase; + if (strings[0].startsWith("@")) { + ResourceLocation resourceLocation = new ResourceLocation(strings[0].substring(1)); + entityLivingBase = EntityViewer.constructEntity(resourceLocation); + } else { + entityLivingBase = EntityViewer.constructEntity(strings[0], Arrays.copyOfRange(strings, 1, strings.length)); + } + if (entityLivingBase == null) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not create that entity")); + return; + } + queuedGUIS.add(new EntityViewer(strings[0], entityLivingBase)); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index 53a7894b..27944c92 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -1,4 +1,4 @@ -package io.github.moulberry.notenoughupdates.commands.dev; + package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/AgeModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/AgeModifier.java new file mode 100644 index 00000000..5884512f --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/AgeModifier.java @@ -0,0 +1,30 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.mixins.AccessorEntityAgeable; +import io.github.moulberry.notenoughupdates.mixins.AccessorEntityArmorStand; +import net.minecraft.entity.EntityAgeable; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.entity.monster.EntityZombie; + +public class AgeModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + boolean baby = info.has("baby") && info.get("baby").getAsBoolean(); + if (base instanceof EntityAgeable) { + ((AccessorEntityAgeable) base).setGrowingAgeDirect(baby ? -1 : 1); + return base; + } + if (base instanceof EntityZombie) { + ((EntityZombie) base).setChild(baby); + return base; + } + if (base instanceof EntityArmorStand) { + ((AccessorEntityArmorStand) base).setSmallDirect(baby); + return base; + } + System.out.println("Cannot apply age to a non ageable entity: " + base); + return null; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/ChargedModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/ChargedModifier.java new file mode 100644 index 00000000..17dce66d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/ChargedModifier.java @@ -0,0 +1,17 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; + +public class ChargedModifier extends EntityViewerModifier { + + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + if (base instanceof EntityCreeper) { + base.getDataWatcher().updateObject(17, (byte) 1); + return base; + } + return null; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java new file mode 100644 index 00000000..e9075e47 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewer.java @@ -0,0 +1,177 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.boss.EntityWither; +import net.minecraft.entity.item.EntityArmorStand; +import net.minecraft.entity.monster.*; +import net.minecraft.entity.passive.*; +import net.minecraft.util.ResourceLocation; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +public class EntityViewer extends GuiScreen { + + public static Map> validEntities = new HashMap>() {{ + put("Zombie", () -> new EntityZombie(null)); + put("Chicken", () -> new EntityChicken(null)); + put("Slime", () -> new EntitySlime(null)); + put("Wolf", () -> new EntityWolf(null)); + put("Skeleton", () -> new EntitySkeleton(null)); + put("Creeper", () -> new EntityCreeper(null)); + put("Ocelot", () -> new EntityOcelot(null)); + put("Blaze", () -> new EntityBlaze(null)); + put("Rabbit", () -> new EntityRabbit(null)); + put("Sheep", () -> new EntitySheep(null)); + put("Horse", () -> new EntityHorse(null)); + put("Eisengolem", () -> new EntityIronGolem(null)); + put("Silverfish", () -> new EntitySilverfish(null)); + put("Witch", () -> new EntityWitch(null)); + put("Endermite", () -> new EntityEndermite(null)); + put("Snowman", () -> new EntitySnowman(null)); + put("Villager", () -> new EntityVillager(null)); + put("Guardian", () -> new EntityGuardian(null)); + put("ArmorStand", () -> new EntityArmorStand(null)); + put("Squid", () -> new EntitySquid(null)); + put("Bat", () -> new EntityBat(null)); + put("Spider", () -> new EntitySpider(null)); + put("CaveSpider", () -> new EntityCaveSpider(null)); + put("Pigman", () -> new EntityPigZombie(null)); + put("Ghast", () -> new EntityGhast(null)); + put("MagmaCube", () -> new EntityMagmaCube(null)); + put("Wither", () -> new EntityWither(null)); + put("Enderman", () -> new EntityEnderman(null)); + put("Mooshroom", ()-> new EntityMooshroom(null)); + put("WitherSkeleton", () -> { + EntitySkeleton skeleton = new EntitySkeleton(null); + skeleton.setSkeletonType(1); + return skeleton; + }); + put("Cow", () -> new EntityCow(null)); + put("Dragon", ()-> new EntityDragon(null)); + put("Player", () -> new GUIClientPlayer()); + }}; + + public static Map validModifiers = new HashMap() {{ + put("playerdata", new SkinModifier()); + put("equipment", new EquipmentModifier()); + put("riding", new RidingModifier()); + put("charged", new ChargedModifier()); + put("witherdata", new WitherModifier()); + put("invisible", new InvisibleModifier()); + put("age", new AgeModifier()); + put("horse", new HorseModifier()); + }}; + + public int guiLeft = 0; + public int guiTop = 0; + public int xSize = 176; + public int ySize = 166; + + private final String label; + private final EntityLivingBase entity; + private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/entity_viewer.png"); + + public EntityViewer(String label, EntityLivingBase entity) { + this.label = label; + this.entity = entity; + } + + public static EntityLivingBase constructEntity(ResourceLocation resourceLocation) { + Gson gson = NotEnoughUpdates.INSTANCE.manager.gson; + try (Reader is = new InputStreamReader( + Minecraft.getMinecraft().getResourceManager().getResource(resourceLocation).getInputStream(), StandardCharsets.UTF_8)) { + return constructEntity(gson.fromJson(is, JsonObject.class)); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + public static EntityLivingBase constructEntity(JsonObject info) { + List modifiers = info.has("modifiers") ? + StreamSupport.stream(info.get("modifiers").getAsJsonArray().spliterator(), false) + .map(JsonElement::getAsJsonObject).collect(Collectors.toList()) + : Collections.emptyList(); + return EntityViewer.constructEntity(info.get("entity").getAsString(), modifiers); + } + + public static EntityLivingBase constructEntity(String string, String[] modifiers) { + Gson gson = NotEnoughUpdates.INSTANCE.manager.gson; + return constructEntity(string, Arrays.stream(modifiers).map(it -> gson.fromJson(it, JsonObject.class)).collect(Collectors.toList())); + } + + public static EntityLivingBase constructEntity(String string, List modifiers) { + Supplier aClass = validEntities.get(string); + if (aClass == null) { + System.err.println("Could not find entity of type: " + string); + return null; + } + try { + EntityLivingBase entity = aClass.get(); + for (JsonObject modifier : modifiers) { + String type = modifier.get("type").getAsString(); + EntityViewerModifier entityViewerModifier = validModifiers.get(type); + entity = entityViewerModifier.applyModifier(entity, modifier); + if (entity == null) break; + } + return entity; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + + this.guiLeft = (width - this.xSize) / 2; + this.guiTop = (height - this.ySize) / 2; + + + Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND); + drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize); + + + Utils.drawStringScaledMaxWidth(label, fontRenderer, guiLeft + 10, guiTop + 10, false, 100, 0xFF00FF); + renderEntity(entity, guiLeft + 90, guiTop + 75, mouseX, mouseY); + } + + public static void renderEntity(EntityLivingBase entity, int posX, int posY, int mouseX, int mouseY) { + GlStateManager.color(1F, 1F, 1F, 1F); + + int scale = 30; + float bottomOffset = 0F; + EntityLivingBase stack = entity; + while (true) { + + stack.ticksExisted = Minecraft.getMinecraft().thePlayer.ticksExisted; + GuiInventory.drawEntityOnScreen(posX, (int) (posY - bottomOffset * scale), scale, posX - mouseX, (int) (posY - stack.getEyeHeight() * scale - mouseY), stack); + bottomOffset += stack.getMountedYOffset(); + if (!(stack.riddenByEntity instanceof EntityLivingBase)) { + break; + } + stack = (EntityLivingBase) stack.riddenByEntity; + } + + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewerModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewerModifier.java new file mode 100644 index 00000000..bab6c354 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EntityViewerModifier.java @@ -0,0 +1,8 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; + +public abstract class EntityViewerModifier { + public abstract EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info); +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EquipmentModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EquipmentModifier.java new file mode 100644 index 00000000..3011e479 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/EquipmentModifier.java @@ -0,0 +1,72 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; + +public class EquipmentModifier extends EntityViewerModifier { + + private ItemStack createItem(String item) { + NEUManager manager = NotEnoughUpdates.INSTANCE.manager; + String[] split = item.split("#"); + if (split.length == 2) { + switch (split[0].intern()) { + case "LEATHER_LEGGINGS": + return coloredLeatherArmor(Items.leather_leggings, split[1]); + case "LEATHER_HELMET": + return coloredLeatherArmor(Items.leather_helmet, split[1]); + case "LEATHER_CHESTPLATE": + return coloredLeatherArmor(Items.leather_chestplate, split[1]); + case "LEATHER_BOOTS": + return coloredLeatherArmor(Items.leather_boots, split[1]); + default: + throw new RuntimeException("Unknown leather piece: " + item); + } + } + return manager.createItem(item); + } + + private ItemStack coloredLeatherArmor(ItemArmor item, String colorHex) { + ItemStack is = new ItemStack(item); + item.setColor(is, Integer.parseInt(colorHex, 16)); + return is; + } + + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + if (info.has("hand")) + setCurrentItemOrArmor(base, 0, createItem(info.get("hand").getAsString())); + if (info.has("helmet")) + setCurrentItemOrArmor(base, 4, createItem(info.get("helmet").getAsString())); + if (info.has("chestplate")) + setCurrentItemOrArmor(base, 3, createItem(info.get("chestplate").getAsString())); + if (info.has("leggings")) + setCurrentItemOrArmor(base, 2, createItem(info.get("leggings").getAsString())); + if (info.has("feet")) + setCurrentItemOrArmor(base, 1, createItem(info.get("feet").getAsString())); + return base; + } + + public void setCurrentItemOrArmor(EntityLivingBase entity, int slot, ItemStack itemStack) { + if (entity instanceof EntityPlayer) { + setPlayerCurrentItemOrArmor((EntityPlayer) entity, slot, itemStack); + } else { + entity.setCurrentItemOrArmor(slot, itemStack); + } + } + + // Biscuit person needs to learn how to code and not fuck up valid vanilla behaviour + public static void setPlayerCurrentItemOrArmor(EntityPlayer player, int slot, ItemStack itemStack) { + if (slot == 0) { + player.inventory.mainInventory[player.inventory.currentItem] = itemStack; + } else { + player.inventory.armorInventory[slot - 1] = itemStack; + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java new file mode 100644 index 00000000..bbff2db1 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java @@ -0,0 +1,40 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.mojang.authlib.GameProfile; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.util.ResourceLocation; + +import java.util.UUID; + +public class GUIClientPlayer extends AbstractClientPlayer { + public GUIClientPlayer() { + super(null, new GameProfile(UUID.randomUUID(), "GuiPlayer")); + } + + ResourceLocation overrideSkin = DefaultPlayerSkin.getDefaultSkinLegacy(); + ResourceLocation overrideCape = null; + boolean overrideIsSlim = false; + NetworkPlayerInfo playerInfo = new NetworkPlayerInfo(this.getGameProfile()) { + @Override + public String getSkinType() { + return overrideIsSlim ? "slim" : "default"; + } + + @Override + public ResourceLocation getLocationSkin() { + return overrideSkin; + } + + @Override + public ResourceLocation getLocationCape() { + return overrideCape; + } + }; + + @Override + protected NetworkPlayerInfo getPlayerInfo() { + return playerInfo; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/HorseModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/HorseModifier.java new file mode 100644 index 00000000..7fd2dadd --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/HorseModifier.java @@ -0,0 +1,66 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public class HorseModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + if (!(base instanceof EntityHorse)) + return null; + EntityHorse horse = (EntityHorse) base; + if (info.has("kind")) { + String type = info.get("kind").getAsString().intern(); + switch (type) { + case "skeleton": + horse.setHorseType(4); + break; + case "zombie": + horse.setHorseType(3); + break; + case "mule": + horse.setHorseType(2); + break; + case "donkey": + horse.setHorseType(1); + break; + case "horse": + horse.setHorseType(0); + break; + default: + throw new IllegalArgumentException("Unknown horse type: " + type); + } + } + if (info.has("armor")) { + JsonElement el = info.get("armor"); + if (el.isJsonNull()) { + horse.setHorseArmorStack(null); + } else { + Item item; + switch (el.getAsString().intern()) { + case "iron": + item = Items.iron_horse_armor; + break; + case "golden": + item = Items.golden_horse_armor; + break; + case "diamond": + item = Items.diamond_horse_armor; + break; + default: + throw new IllegalArgumentException("Unknown horse armor: " + el.getAsString()); + } + horse.setHorseArmorStack(new ItemStack(item)); + } + } + if (info.has("saddled")) { + horse.setHorseSaddled(info.get("saddled").getAsBoolean()); + } + return horse; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/InvisibleModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/InvisibleModifier.java new file mode 100644 index 00000000..c2138b3f --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/InvisibleModifier.java @@ -0,0 +1,12 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; + +public class InvisibleModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + base.setInvisible(!info.has("invisible") || info.get("invisible").getAsBoolean()); + return base; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/RidingModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/RidingModifier.java new file mode 100644 index 00000000..9879542a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/RidingModifier.java @@ -0,0 +1,14 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; + +public class RidingModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + EntityLivingBase newEntity = EntityViewer.constructEntity(info); + if (newEntity == null) return null; + newEntity.mountEntity(base); + return base; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/SkinModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/SkinModifier.java new file mode 100644 index 00000000..55e8a432 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/SkinModifier.java @@ -0,0 +1,46 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EnumPlayerModelParts; +import net.minecraft.util.ResourceLocation; + +import java.util.Map; + +public class SkinModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + if (base instanceof GUIClientPlayer) { + GUIClientPlayer player = (GUIClientPlayer) base; + if (info.has("cape")) { + player.overrideCape = new ResourceLocation(info.get("cape").getAsString()); + } + if (info.has("skin")) { + player.overrideSkin = new ResourceLocation(info.get("skin").getAsString()); + } + if (info.has("slim")) { + player.overrideIsSlim = info.get("slim").getAsBoolean(); + } + if (info.has("parts")) { + JsonElement parts = info.get("parts"); + byte partBitField = player.getDataWatcher().getWatchableObjectByte(10); + if (parts.isJsonPrimitive() && parts.getAsJsonPrimitive().isBoolean()) { + partBitField = parts.getAsBoolean() ? (byte) -1 : 0; + } else { + JsonObject obj = parts.getAsJsonObject(); + for (Map.Entry part : obj.entrySet()) { + EnumPlayerModelParts modelPart = EnumPlayerModelParts.valueOf(part.getKey()); + if (part.getValue().getAsBoolean()) { + partBitField |= modelPart.getPartMask(); + } else { + partBitField &= ~modelPart.getPartMask(); + } + } + } + player.getDataWatcher().updateObject(10, partBitField); + } + } + return base; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/WitherModifier.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/WitherModifier.java new file mode 100644 index 00000000..c5580f17 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/WitherModifier.java @@ -0,0 +1,29 @@ +package io.github.moulberry.notenoughupdates.miscfeatures.entityviewer; + +import com.google.gson.JsonObject; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityWither; + +public class WitherModifier extends EntityViewerModifier { + @Override + public EntityLivingBase applyModifier(EntityLivingBase base, JsonObject info) { + if (!(base instanceof EntityWither)) + return null; + EntityWither wither = (EntityWither) base; + if (info.has("tiny")) { + if (info.get("tiny").getAsBoolean()) { + wither.setInvulTime(800); + } else { + wither.setInvulTime(0); + } + } + if (info.has("armored")) { + if (info.get("armored").getAsBoolean()) { + wither.setHealth(1); + } else { + wither.setHealth(wither.getMaxHealth()); + } + } + return base; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java index 63a4d6d8..be9ce6c7 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList; import io.github.moulberry.notenoughupdates.NEUManager; import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; import io.github.moulberry.notenoughupdates.recipes.RecipeSlot; +import io.github.moulberry.notenoughupdates.recipes.RecipeType; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; @@ -12,6 +13,7 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Keyboard; @@ -20,48 +22,65 @@ import org.lwjgl.opengl.GL11; import java.awt.*; import java.io.IOException; -import java.util.ArrayList; import java.util.List; +import java.util.*; public class GuiItemRecipe extends GuiScreen { public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png"); + public static final ResourceLocation tabsTexture = new ResourceLocation("notenoughupdates", "textures/gui/tab.png"); public static final int SLOT_SIZE = 16; public static final int SLOT_SPACING = SLOT_SIZE + 2; public static final int BUTTON_WIDTH = 7; public static final int BUTTON_HEIGHT = 11; - public static final int BUTTON_POSITION_Y = 63; - public static final int BUTTON_POSITION_LEFT_X = 110; - public static final int BUTTON_POSITION_RIGHT_X = 147; - public static final int PAGE_STRING_X = 132; - public static final int PAGE_STRING_Y = 69; public static final int TITLE_X = 28; public static final int TITLE_Y = 6; public static final int HOTBAR_SLOT_X = 8; - public static final int HOTBAR_SLOT_Y = 142; + public static final int HOTBAR_SLOT_Y = 197; public static final int PLAYER_INVENTORY_X = 8; - public static final int PLAYER_INVENTORY_Y = 84; + public static final int PLAYER_INVENTORY_Y = 140; + public static final int TAB_POS_X = -26; + public static final int TAB_POS_Y = 8; + public static final int TAB_OFFSET_Y = 30; + public static final int TAB_SIZE_X = 26; + public static final int TAB_SIZE_Y = 30; + public static final int TAB_TEXTURE_SIZE_X = 29; private int currentIndex = 0; + private int currentTab = 0; - private final String title; - private final List craftingRecipes; + private final Map> craftingRecipes = new HashMap<>(); + private final List tabs = new ArrayList<>(); private final NEUManager manager; public int guiLeft = 0; public int guiTop = 0; public int xSize = 176; - public int ySize = 166; + public int ySize = 222; - public GuiItemRecipe(String title, List craftingRecipes, NEUManager manager) { - this.craftingRecipes = craftingRecipes; + public GuiItemRecipe(List unsortedRecipes, NEUManager manager) { this.manager = manager; - this.title = title; + + for (NeuRecipe recipe : unsortedRecipes) { + craftingRecipes.computeIfAbsent(recipe.getType(), ignored -> new ArrayList<>()).add(recipe); + if (!tabs.contains(recipe.getType())) + tabs.add(recipe.getType()); + } } public NeuRecipe getCurrentRecipe() { - currentIndex = MathHelper.clamp_int(currentIndex, 0, craftingRecipes.size()); - return craftingRecipes.get(currentIndex); + List currentRecipes = getCurrentRecipeList(); + currentIndex = MathHelper.clamp_int(currentIndex, 0, currentRecipes.size() - 1); + return currentRecipes.get(currentIndex); + } + + public List getCurrentRecipeList() { + return craftingRecipes.get(getCurrentTab()); + } + + public RecipeType getCurrentTab() { + currentTab = MathHelper.clamp_int(currentTab, 0, tabs.size() - 1); + return tabs.get(currentTab); } public boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) { @@ -90,17 +109,19 @@ public class GuiItemRecipe extends GuiScreen { Minecraft.getMinecraft().getTextureManager().bindTexture(currentRecipe.getBackground()); this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize); + drawTabs(); + currentRecipe.drawExtraBackground(this, mouseX, mouseY); List slots = getAllRenderedSlots(); for (RecipeSlot slot : slots) { - Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this)); + Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this), true); } - if (craftingRecipes.size() > 1) drawArrows(mouseX, mouseY); + drawArrows(currentRecipe, mouseX, mouseY); Utils.drawStringScaledMaxWidth( - title, + currentRecipe.getTitle(), fontRendererObj, guiLeft + TITLE_X, guiTop + TITLE_Y, @@ -126,42 +147,104 @@ public class GuiItemRecipe extends GuiScreen { } } currentRecipe.drawHoverInformation(this, mouseX, mouseY); + drawTabHoverInformation(mouseX, mouseY); + } + + private void drawTabHoverInformation(int mouseX, int mouseY) { + if (tabs.size() < 2) return; + for (int i = 0; i < tabs.size(); i++) { + if (isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + TAB_POS_X, + TAB_POS_Y + TAB_OFFSET_Y * i, + TAB_SIZE_X, + TAB_SIZE_Y + )) { + RecipeType type = tabs.get(i); + Utils.drawHoveringText( + Arrays.asList( + "" + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + type.getLabel(), + "" + EnumChatFormatting.RESET + EnumChatFormatting.GRAY + craftingRecipes.get(type).size() + " Recipes" + ), + mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj + ); + return; + } + } } - private void drawArrows(int mouseX, int mouseY) { + private void drawTabs() { + if (tabs.size() < 2) return; + for (int i = 0; i < tabs.size(); i++) { + RecipeType recipeType = tabs.get(i); + int tabPosX = guiLeft + TAB_POS_X, tabPosY = guiTop + TAB_OFFSET_Y * i + TAB_POS_Y; + int textureOffset = 0; + if (currentTab == i) { + textureOffset = 30; + } + Minecraft.getMinecraft().getTextureManager().bindTexture(tabsTexture); + drawTexturedModalRect( + tabPosX, tabPosY, + 0, textureOffset, + TAB_TEXTURE_SIZE_X, TAB_SIZE_Y + ); + Utils.drawItemStack(recipeType.getIcon(), tabPosX + 7, tabPosY + 7); + } + } + + public static final int BUTTON_POSITION_RIGHT_OFFSET_X = 37; + public static final int PAGE_STRING_OFFSET_X = 22; + public static final int PAGE_STRING_OFFSET_Y = 6; + + private void drawArrows( + NeuRecipe currentRecipe, + int mouseX, + int mouseY + ) { + int recipeCount = getCurrentRecipeList().size(); + if (recipeCount < 2) return; + int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner(); + int buttonPositionLeftX = topLeft[0]; + int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; + int pageStringX = buttonPositionLeftX + PAGE_STRING_OFFSET_X; + int buttonPositionY = topLeft[1]; + int pageStringY = buttonPositionY + PAGE_STRING_OFFSET_Y; + boolean leftSelected = isWithinRect( mouseX - guiLeft, mouseY - guiTop, - BUTTON_POSITION_LEFT_X, - BUTTON_POSITION_Y, + buttonPositionLeftX, + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT ); boolean rightSelected = isWithinRect( mouseX - guiLeft, mouseY - guiTop, - BUTTON_POSITION_RIGHT_X, - BUTTON_POSITION_Y, + buttonPositionRightX, + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT ); - Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture); - Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_LEFT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT, - 34 / 256f, 48 / 256f, - leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f - ); - Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_RIGHT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT, - 10 / 256f, 24 / 256f, - rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f - ); + if (currentIndex != 0) + Utils.drawTexturedRect(guiLeft + buttonPositionLeftX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, + 34 / 256f, 48 / 256f, + leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f + ); + if (currentIndex != recipeCount - 1) + Utils.drawTexturedRect(guiLeft + buttonPositionRightX, guiTop + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, + 10 / 256f, 24 / 256f, + rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f + ); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); - String selectedPage = (currentIndex + 1) + "/" + craftingRecipes.size(); + String selectedPage = (currentIndex + 1) + "/" + recipeCount; Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj, - guiLeft + PAGE_STRING_X, guiTop + PAGE_STRING_Y, false, 24, Color.BLACK.getRGB() + guiLeft + pageStringX, guiTop + pageStringY, false, 24, Color.BLACK.getRGB() ); } @@ -196,12 +279,12 @@ public class GuiItemRecipe extends GuiScreen { int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth; int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1; int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); - + if (Keyboard.getEventKeyState()) return; for (RecipeSlot slot : getAllRenderedSlots()) { if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { ItemStack itemStack = slot.getItemStack(); - if (keyPressed == manager.keybindViewRecipe.getKeyCode()) { // TODO: rework this so it doesnt skip recipe chains - manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), ""); + if (keyPressed == manager.keybindViewRecipe.getKeyCode()) { + manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack)); } else if (keyPressed == manager.keybindViewUsages.getKeyCode()) { manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack)); } @@ -212,16 +295,22 @@ public class GuiItemRecipe extends GuiScreen { @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { super.mouseClicked(mouseX, mouseY, mouseButton); + NeuRecipe currentRecipe = getCurrentRecipe(); + int[] topLeft = currentRecipe.getPageFlipPositionLeftTopCorner(); + int buttonPositionLeftX = topLeft[0]; + int buttonPositionRightX = buttonPositionLeftX + BUTTON_POSITION_RIGHT_OFFSET_X; + int buttonPositionY = topLeft[1]; if (isWithinRect( mouseX - guiLeft, mouseY - guiTop, - BUTTON_POSITION_LEFT_X, - BUTTON_POSITION_Y, + buttonPositionLeftX, + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT - )) { - currentIndex = currentIndex == 0 ? 0 : currentIndex - 1; + ) && + currentIndex > 0) { + currentIndex = currentIndex - 1; Utils.playPressSound(); return; } @@ -229,21 +318,37 @@ public class GuiItemRecipe extends GuiScreen { if (isWithinRect( mouseX - guiLeft, mouseY - guiTop, - BUTTON_POSITION_RIGHT_X, - BUTTON_POSITION_Y, + buttonPositionRightX, + buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT - )) { - currentIndex = currentIndex == craftingRecipes.size() - 1 ? currentIndex : currentIndex + 1; + ) && + currentIndex < getCurrentRecipeList().size()) { + currentIndex = currentIndex + 1; Utils.playPressSound(); return; } + for (int i = 0; i < tabs.size(); i++) { + if (isWithinRect( + mouseX - guiLeft, + mouseY - guiTop, + TAB_POS_X, + TAB_POS_Y + TAB_OFFSET_Y * i, + TAB_SIZE_X, + TAB_SIZE_Y + )) { + currentTab = i; + Utils.playPressSound(); + return; + } + } + for (RecipeSlot slot : getAllRenderedSlots()) { if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) { ItemStack itemStack = slot.getItemStack(); if (mouseButton == 0) { - manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), ""); + manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack)); } else if (mouseButton == 1) { manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack)); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityAgeable.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityAgeable.java new file mode 100644 index 00000000..9228f93d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityAgeable.java @@ -0,0 +1,12 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.EntityAgeable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(EntityAgeable.class) +public interface AccessorEntityAgeable { + @Accessor(value = "growingAge") + void setGrowingAgeDirect(int newValue); + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityArmorStand.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityArmorStand.java new file mode 100644 index 00000000..b6a3ca6e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorEntityArmorStand.java @@ -0,0 +1,12 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.item.EntityArmorStand; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(EntityArmorStand.class) +public interface AccessorEntityArmorStand { + @Invoker(value = "setSmall") + void setSmallDirect(boolean isSmall); + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorMinecraft.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorMinecraft.java new file mode 100644 index 00000000..0277a18b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/AccessorMinecraft.java @@ -0,0 +1,14 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResourcePack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(Minecraft.class) +public interface AccessorMinecraft { + @Accessor(value = "defaultResourcePacks") + List onGetDefaultResourcePacks(); +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java index b8f07b53..801b9041 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityAgeable.java @@ -3,6 +3,7 @@ package io.github.moulberry.notenoughupdates.mixins; import net.minecraft.entity.EntityAgeable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityHorse.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityHorse.java new file mode 100644 index 00000000..fe88922e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntityHorse.java @@ -0,0 +1,17 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(EntityHorse.class) +public class MixinEntityHorse { + @Redirect(method = "updateHorseSlots", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isRemote:Z")) + public boolean onUpdateHorseSlots(World instance) { + if (instance == null) + return true; + return instance.isRemote; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntitySkeleton.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntitySkeleton.java new file mode 100644 index 00000000..54fe53f3 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinEntitySkeleton.java @@ -0,0 +1,17 @@ +package io.github.moulberry.notenoughupdates.mixins; + +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(EntitySkeleton.class) +public class MixinEntitySkeleton { + @Redirect(method = "setCurrentItemOrArmor", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isRemote:Z")) + public boolean onSetCurrentItemOrArmor(World instance) { + if (instance == null) + return true; + return instance.isRemote; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 2fba6e80..68449ba8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -150,6 +150,10 @@ public class NEUConfig extends Config { return; case 20: FairySouls.getInstance().setTrackFairySouls(NotEnoughUpdates.INSTANCE.config.misc.trackFairySouls); + return; + case 21: + NotEnoughUpdates.INSTANCE.overlay.updateSearch(); + return; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java index 3e5a4cdf..db154c24 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Itemlist.java @@ -107,4 +107,14 @@ public class Itemlist { ) @ConfigEditorColour public String backgroundColour = "15:6:0:0:255"; + + @Expose + @ConfigOption( + name = "Always show Monsters", + desc = "Always show Monster Items in the item list" + ) + @ConfigEditorBoolean( + runnableId = 21 + ) + public boolean alwaysShowMonsters = false; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 11c10ea0..691ccaae 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -2222,7 +2222,7 @@ public class GuiProfileViewer extends GuiScreen { } Panorama.drawPanorama(-backgroundRotation, guiLeft + 212, guiTop + 44, 81, 108, -0.37f, 0.6f, - getPanoramasForLocation(location == null ? "dynamic" : location, panoramaIdentifier) + Panorama.getPanoramasForLocation(location == null ? "dynamic" : location, panoramaIdentifier) ); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_pets); @@ -3114,38 +3114,6 @@ public class GuiProfileViewer extends GuiScreen { return entityPlayer; } - public ResourceLocation[] getPanoramasForLocation(String location, String identifier) { - if (panoramasMap.containsKey(location + identifier)) return panoramasMap.get(location + identifier); - try { - ResourceLocation[] panoramasArray = new ResourceLocation[6]; - for (int i = 0; i < 6; i++) { - panoramasArray[i] = - new ResourceLocation("notenoughupdates:panoramas/" + location + "_" + identifier + "/panorama_" + i + ".jpg"); - Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]); - } - panoramasMap.put(location + identifier, panoramasArray); - return panoramasArray; - } catch (IOException e) { - try { - ResourceLocation[] panoramasArray = new ResourceLocation[6]; - for (int i = 0; i < 6; i++) { - panoramasArray[i] = - new ResourceLocation("notenoughupdates:panoramas/" + location + "/panorama_" + i + ".jpg"); - Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]); - } - panoramasMap.put(location + identifier, panoramasArray); - return panoramasArray; - } catch (IOException e2) { - ResourceLocation[] panoramasArray = new ResourceLocation[6]; - for (int i = 0; i < 6; i++) { - panoramasArray[i] = new ResourceLocation("notenoughupdates:panoramas/unknown/panorama_" + i + ".jpg"); - } - panoramasMap.put(location + identifier, panoramasArray); - return panoramasArray; - } - } - } - private void drawExtraPage(int mouseX, int mouseY, float partialTicks) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -4717,7 +4685,7 @@ public class GuiProfileViewer extends GuiScreen { } Panorama.drawPanorama(-backgroundRotation - extraRotation, guiLeft + 23, guiTop + 44, 81, 108, 0.37f, 0.8f, - getPanoramasForLocation(location == null ? "unknown" : location, panoramaIdentifier) + Panorama.getPanoramasForLocation(location == null ? "unknown" : location, panoramaIdentifier) ); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_basic); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java index ac117bc2..a2d297f5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java @@ -15,6 +15,9 @@ import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.Project; +import java.io.IOException; +import java.util.HashMap; + public class Panorama { private static final TexLoc tl = new TexLoc(97, 19, Keyboard.KEY_P); private static final TexLoc tl2 = new TexLoc(37, 80, Keyboard.KEY_L); @@ -24,6 +27,41 @@ public class Panorama { private static int lastWidth = 0; private static int lastHeight = 0; + + private static final HashMap panoramasMap = new HashMap<>(); + + public static synchronized ResourceLocation[] getPanoramasForLocation(String location, String identifier) { + if (panoramasMap.containsKey(location + ident