diff --git a/src/main/java/electroblob/wizardry/CommonProxy.java b/src/main/java/electroblob/wizardry/CommonProxy.java index 9220e64f..e13fcc28 100644 --- a/src/main/java/electroblob/wizardry/CommonProxy.java +++ b/src/main/java/electroblob/wizardry/CommonProxy.java @@ -43,6 +43,10 @@ public class CommonProxy { public void registerRenderers(){} + public void registerItemColorHandlers(){} + + public void registerModelProperties(){} + public void initialiseLayers(){} public void initialiseAnimations(){} diff --git a/src/main/java/electroblob/wizardry/Settings.java b/src/main/java/electroblob/wizardry/Settings.java index ffa84f2a..8b075bd5 100644 --- a/src/main/java/electroblob/wizardry/Settings.java +++ b/src/main/java/electroblob/wizardry/Settings.java @@ -355,6 +355,8 @@ public final class Settings { * velocity-based one. */ public boolean replaceVanillaFallDamage = true; + /** [Synchronised] Whether spell book colors are only shown when the player has the Archivist's Eyeglass equipped. */ + public boolean spellBookColorsRequireArchivistsEyeglass = false; /** [Synchronised] Chance of 'misreading' an undiscovered spell and triggering a forfeit instead. */ public double forfeitChance = 0.2; /** [Synchronised] Progression requirements for upgrading a wand to each tier. */ @@ -461,6 +463,8 @@ public final class Settings { public static final String DEFAULT_HUD_SKIN_KEY = "default"; // Defined here so it's not in a client-only class. /** [Client-only] The string identifier of the skin used for the spell HUD. */ public String spellHUDSkin = DEFAULT_HUD_SKIN_KEY; + /** [Client-only] Whether to show elemental colors on spell books for discovered spells. */ + public boolean spellBookColors = true; /** Set of constants for each of the eight positions that the spell HUD can be in. */ public enum GuiPosition { @@ -1103,6 +1107,13 @@ public final class Settings { replaceVanillaFallDamage = property.getBoolean(); propOrder.add(property.getName()); + property = config.get(TWEAKS_CATEGORY, "spellBookColorsRequireArchivistsEyeglass", false, + "If true, spell book colors are only shown when the player has the charm of spell discovery equipped."); + property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_colors_require_charm"); + Wizardry.proxy.setToNamedBooleanEntry(property); + spellBookColorsRequireArchivistsEyeglass = property.getBoolean(); + propOrder.add(property.getName()); + property = config.get(TWEAKS_CATEGORY, "blindnessTweak", true, "Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed."); property.setLanguageKey("config." + Wizardry.MODID + ".blindness_tweak"); @@ -1487,6 +1498,14 @@ public final class Settings { Wizardry.proxy.setToNamedBooleanEntry(property); showChargeMeter = property.getBoolean(); propOrder.add(property.getName()); + + property = config.get(CLIENT_CATEGORY, "spellBookColors", true, "Whether to show elemental colors on spell books for discovered spells."); + property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_colors"); + property.setRequiresWorldRestart(false); + Wizardry.proxy.setToNamedBooleanEntry(property); + spellBookColors = property.getBoolean(); + propOrder.add(property.getName()); + property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes."); property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook"); property.setRequiresWorldRestart(false); diff --git a/src/main/java/electroblob/wizardry/Wizardry.java b/src/main/java/electroblob/wizardry/Wizardry.java index 41279087..c7497ceb 100644 --- a/src/main/java/electroblob/wizardry/Wizardry.java +++ b/src/main/java/electroblob/wizardry/Wizardry.java @@ -198,6 +198,8 @@ public class Wizardry { // Client-side stuff (via proxies) proxy.initGuiBits(); proxy.registerParticles(); + proxy.registerItemColorHandlers(); + proxy.registerModelProperties(); proxy.registerSoundEventListener(); } diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 7e9545dd..4915fe45 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -1,7 +1,6 @@ package electroblob.wizardry.client; import electroblob.wizardry.CommonProxy; -import electroblob.wizardry.Settings; import electroblob.wizardry.Wizardry; import electroblob.wizardry.block.BlockBookshelf; import electroblob.wizardry.client.animation.ActionAnimation; @@ -19,6 +18,8 @@ import electroblob.wizardry.client.model.ModelRobeArmour; import electroblob.wizardry.client.model.ModelSageArmour; import electroblob.wizardry.client.model.ModelWizardArmour; import electroblob.wizardry.client.particle.*; +import electroblob.wizardry.constants.Element; +import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory; import electroblob.wizardry.client.renderer.RenderSpectralGolem; import electroblob.wizardry.client.renderer.entity.*; @@ -38,6 +39,7 @@ import electroblob.wizardry.entity.projectile.*; import electroblob.wizardry.event.SpellCastEvent; import electroblob.wizardry.event.SpellCastEvent.Source; import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration; +import electroblob.wizardry.item.ItemArtefact; import electroblob.wizardry.item.ItemScroll; import electroblob.wizardry.item.ItemSpellBook; import electroblob.wizardry.item.ItemWand; @@ -877,4 +879,64 @@ public class ClientProxy extends CommonProxy { ClientRegistry.bindTileEntitySpecialRenderer(TileEntityImbuementAltar.class, new RenderImbuementAltar()); } + + public void registerItemColorHandlers() { + Minecraft.getMinecraft().getItemColors().registerItemColorHandler((stack, tintIndex) -> { + if (Wizardry.settings.spellBookColors && tintIndex == 1) { // layer 1 is the overlay + Spell spell = Spell.byMetadata(stack.getMetadata()); + + if (shouldDisplayDiscovered(spell, stack)) { + // Even if the spell is discovered, the charm might be required for colouration + if(Wizardry.settings.spellBookColorsRequireArchivistsEyeglass && !ItemArtefact.isArtefactActive(getThePlayer(), WizardryItems.charm_spell_discovery)) { + return -1; + } + + Element element = spell.getElement(); + if (element != null) { + switch (element) { + case MAGIC: + return 0xAAAAAA; // GRAY + case FIRE: + return 0xAA0000; // DARK_RED + case ICE: + return 0x55FFFF; // AQUA + case LIGHTNING: + return 0x00AAAA; // DARK_AQUA + case NECROMANCY: + return 0xAA00AA; // DARK_PURPLE + case EARTH: + return 0x00AA00; // DARK_GREEN + case SORCERY: + return 0x55FF55; // GREEN + case HEALING: + return 0xFFFF55; // YELLOW + } + } + } + } + return -1; + }, WizardryItems.spell_book); + } + + public void registerModelProperties() { + Item spellBook = WizardryItems.spell_book; + ResourceLocation discoveredProperty = new ResourceLocation(Wizardry.MODID, "discovered"); + + spellBook.addPropertyOverride(discoveredProperty, (stack, world, entity) -> { + if (!Wizardry.settings.spellBookColors) return 0.0f; + + boolean discovered = shouldDisplayDiscovered(Spell.byMetadata(stack.getMetadata()), stack); + + if(discovered && Wizardry.settings.spellBookColorsRequireArchivistsEyeglass){ + // Entity can be null so we have to check + if(entity instanceof EntityPlayer){ + return ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.charm_spell_discovery) ? 1.0f : 0.0f; + } + // If there's no entity, there's no charm, so no colour + return 0.0f; + } + + return discovered ? 1.0f : 0.0f; + }); + } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java index 258c15be..6b899c6d 100644 --- a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java +++ b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java @@ -1,5 +1,6 @@ package electroblob.wizardry.client; +import electroblob.wizardry.Wizardry; import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect; import electroblob.wizardry.data.DispenserCastingData; import electroblob.wizardry.data.SpellEmitterData; @@ -13,7 +14,6 @@ import electroblob.wizardry.spell.SixthSense; import electroblob.wizardry.spell.SlowTime; import electroblob.wizardry.spell.Transience; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.BufferBuilder; @@ -31,6 +31,9 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.event.entity.player.ItemTooltipEvent; import org.lwjgl.opengl.GL11; import java.util.ArrayList; @@ -196,6 +199,15 @@ public final class WizardryClientEventHandler { } } + @SubscribeEvent + public static void onItemTooltip(ItemTooltipEvent event) { + if (event.getItemStack().getItem() == WizardryItems.charm_spell_discovery) { + if (Wizardry.settings.spellBookColorsRequireArchivistsEyeglass) { + event.getToolTip().add(TextFormatting.GRAY + I18n.format("item.ebwizardry:charm_spell_discovery.desc.color")); + } + } + } + /** * Renders an overlay across the entire screen. * @param resolution The screen resolution diff --git a/src/main/resources/assets/ebwizardry/lang/en_us.lang b/src/main/resources/assets/ebwizardry/lang/en_us.lang index cd93fd80..ecf9d1f8 100644 --- a/src/main/resources/assets/ebwizardry/lang/en_us.lang +++ b/src/main/resources/assets/ebwizardry/lang/en_us.lang @@ -524,6 +524,7 @@ item.ebwizardry\:charm_move_speed.name=Icarus Medallion item.ebwizardry\:charm_move_speed.desc=Move at near-full speed when casting spells item.ebwizardry\:charm_spell_discovery.name=Archivist's Eyeglass item.ebwizardry\:charm_spell_discovery.desc=Spell books found in chests are much more likely to be ones you have not yet discovered +item.ebwizardry\:charm_spell_discovery.desc.color=When equipped, you can see the element of a known spell book by the color of its bookmark item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar item.ebwizardry\:charm_lava_walking.name=Nether Ice Core @@ -1692,6 +1693,10 @@ config.ebwizardry.replace_vanilla_fall_damage=Replace Vanilla Fall Damage config.ebwizardry.replace_vanilla_fall_damage.tooltip=Whether to replace Minecraft's distance-based fall damage calculation with an equivalent, velocity-based one. This is done such that mobs in freefall will take exactly the same damage as normal, so it will not break falling-based mob farms. Disable this if you experience falling-related weirdness! If this is disabled, some spells revert to a more simplistic method of resetting the player's fall damage in certain cases. config.ebwizardry.replace_vanilla_fall_damage.true=Yes - it's parkour time config.ebwizardry.replace_vanilla_fall_damage.false=No - break my legs normally +config.ebwizardry.spell_book_colors_require_charm=Spell Book Colors Require Archivist's Eyeglass +config.ebwizardry.spell_book_colors_require_charm.tooltip=Whether to require the Archivist's Eyeglass charm artifact to see colored spell book bookmarks. +config.ebwizardry.spell_book_colors_require_charm.true=Yes - I want to see the colours only if the charm is worn +config.ebwizardry.spell_book_colors_require_charm.false=No - I want to see the colours all the time config.ebwizardry.blindness_tweak=Blindness Tweak config.ebwizardry.blindness_tweak.tooltip=Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed. config.ebwizardry.mob_loot_table_whitelist=Mob Loot Table Whitelist diff --git a/src/main/resources/assets/ebwizardry/models/item/spell_book.json b/src/main/resources/assets/ebwizardry/models/item/spell_book.json index b5941b77..7ad16e32 100644 --- a/src/main/resources/assets/ebwizardry/models/item/spell_book.json +++ b/src/main/resources/assets/ebwizardry/models/item/spell_book.json @@ -1,14 +1,17 @@ { - "parent": "item/generated", - "textures": { - "layer0": "ebwizardry:items/spell_book" - }, + "parent": "ebwizardry:item/spell_book_undiscovered", "overrides": [ { "predicate": { "festive": 1 }, "model": "ebwizardry:item/festive_spell_book" + }, + { + "predicate": { + "ebwizardry:discovered": 1 + }, + "model": "ebwizardry:item/spell_book_discovered" } ] } \ No newline at end of file diff --git a/src/main/resources/assets/ebwizardry/models/item/spell_book_discovered.json b/src/main/resources/assets/ebwizardry/models/item/spell_book_discovered.json new file mode 100644 index 00000000..065ae4d8 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/spell_book_discovered.json @@ -0,0 +1,7 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ebwizardry:items/spell_book", + "layer1": "ebwizardry:items/spell_book_overlay" + } +} diff --git a/src/main/resources/assets/ebwizardry/models/item/spell_book_undiscovered.json b/src/main/resources/assets/ebwizardry/models/item/spell_book_undiscovered.json new file mode 100644 index 00000000..834e5195 --- /dev/null +++ b/src/main/resources/assets/ebwizardry/models/item/spell_book_undiscovered.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "ebwizardry:items/spell_book" + } +} diff --git a/src/main/resources/assets/ebwizardry/textures/items/spell_book_overlay.png b/src/main/resources/assets/ebwizardry/textures/items/spell_book_overlay.png new file mode 100644 index 00000000..54b4e48c Binary files /dev/null and b/src/main/resources/assets/ebwizardry/textures/items/spell_book_overlay.png differ