diff --git a/src/main/java/com/minelittlepony/unicopia/ability/Ability.java b/src/main/java/com/minelittlepony/unicopia/ability/Ability.java index 3a5721fe..7bd9dc03 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/Ability.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/Ability.java @@ -91,17 +91,25 @@ public interface Ability { /** * The icon representing this ability on the UI and HUD. */ - default Identifier getIcon(Pony player, boolean swap) { + default Identifier getIcon(Pony player) { Identifier id = Abilities.REGISTRY.getId(this); return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + ".png"); } + default Text getName(Pony player) { + return getName(); + } + /** * The display name for this ability. */ default Text getName() { + return Text.translatable(getTranslationKey()); + } + + default String getTranslationKey() { Identifier id = Abilities.REGISTRY.getId(this); - return Text.translatable("ability." + id.getNamespace() + "." + id.getPath().replace('/', '.')); + return "ability." + id.getNamespace() + "." + id.getPath().replace('/', '.'); } /** diff --git a/src/main/java/com/minelittlepony/unicopia/ability/AbilitySlot.java b/src/main/java/com/minelittlepony/unicopia/ability/AbilitySlot.java index 9aefaa1b..5adb408d 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/AbilitySlot.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/AbilitySlot.java @@ -1,21 +1,24 @@ package com.minelittlepony.unicopia.ability; public enum AbilitySlot { + /** + * No slot. Corresponds to abilities that are not equipped. + */ NONE, /** - * The primary ability. Corresponds to the largest ring in the HUD + * The primary ability slot. Corresponds to the largest ring in the HUD */ PRIMARY, /** - * THe secondary ability. Corresponds to the top small ring in the HUD + * The secondary ability slot. Corresponds to the top small ring in the HUD */ SECONDARY, /** - * The tertiary ability. Corresponds to the bottom small ring in the HUD. + * The tertiary ability slot. Corresponds to the bottom small ring in the HUD. */ TERTIARY, /** - * The passive primary ability. Appears in place of the primary ability whilst sneaking. + * The passive primary ability slot. Appears in place of the primary ability whilst sneaking. */ PASSIVE; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/AbstractSpellCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/AbstractSpellCastingAbility.java new file mode 100644 index 00000000..e583eec2 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/AbstractSpellCastingAbility.java @@ -0,0 +1,70 @@ +package com.minelittlepony.unicopia.ability; + +import com.minelittlepony.unicopia.*; +import com.minelittlepony.unicopia.ability.data.Hit; +import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.particle.MagicParticleEffect; + +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.TypedActionResult; + +abstract class AbstractSpellCastingAbility implements Ability { + + @Override + public int getCooldownTime(Pony player) { + return 0; + } + + @Override + public boolean canUse(Race race) { + return race.canCast(); + } + + @Override + public Text getName(Pony player) { + CustomisedSpellType spell = player.getCharms().getEquippedSpell(player.getCharms().getHand()); + TypedActionResult> gemSpell = player.getCharms().getSpellInHand(false); + var active = !player.getAbilities().getStat(AbilitySlot.PRIMARY).getActiveAbility().isEmpty(); + if (!spell.isEmpty()) { + if (active) { + if (gemSpell.getResult().isAccepted()) { + return Text.translatable(getTranslationKey() + ".with_spell.hand", + gemSpell.getValue().type().getName().copy().formatted(gemSpell.getValue().type().getAffinity().getColor()) + ); + } + + return Text.translatable(getTranslationKey() + ".with_spell.active", + spell.type().getName().copy().formatted(spell.type().getAffinity().getColor()) + ); + } + + return Text.translatable(getTranslationKey() + ".with_spell" + (gemSpell.getResult().isAccepted() ? ".replacing" : ""), + spell.type().getName().copy().formatted(spell.type().getAffinity().getColor()), + gemSpell.getValue().type().getName().copy().formatted(gemSpell.getValue().type().getAffinity().getColor()) + ); + } + return getName(); + } + + @Override + public int getColor(Pony player) { + TypedActionResult> newSpell = player.getCharms().getSpellInHand(false); + + if (newSpell.getResult() != ActionResult.FAIL) { + return newSpell.getValue().type().getColor(); + } + return -1; + } + + @Override + public Hit.Serializer getSerializer() { + return Hit.SERIALIZER; + } + + @Override + public void postApply(Pony player, AbilitySlot slot) { + player.spawnParticles(MagicParticleEffect.UNICORN, 5); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/PegasusFlightToggleAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/PegasusFlightToggleAbility.java index e8643062..5ac0d19e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/PegasusFlightToggleAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/PegasusFlightToggleAbility.java @@ -39,7 +39,7 @@ public class PegasusFlightToggleAbility implements Ability { } @Override - public Identifier getIcon(Pony player, boolean swap) { + public Identifier getIcon(Pony player) { Identifier id = Abilities.REGISTRY.getId(this); return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (player.getPhysics().isFlying() ? "_land" : "_takeoff") diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java index e87472af..d0c80bac 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornCastingAbility.java @@ -33,23 +33,13 @@ import net.minecraft.util.math.random.Random; * 2. If the player is holding a gem, consumes it and casts whatever spell is contained within onto the user. * 3. If the player is holding a amulet, charges it. */ -public class UnicornCastingAbility implements Ability { +public class UnicornCastingAbility extends AbstractSpellCastingAbility { @Override public int getWarmupTime(Pony player) { return 20; } - @Override - public int getCooldownTime(Pony player) { - return 0; - } - - @Override - public boolean canUse(Race race) { - return race.canCast(); - } - @Override @Nullable public Hit tryActivate(Pony player) { @@ -59,11 +49,6 @@ public class UnicornCastingAbility implements Ability { return Hit.of(player.getMagicalReserves().getMana().get() >= getCostEstimate(player)); } - @Override - public Hit.Serializer getSerializer() { - return Hit.SERIALIZER; - } - @Override public double getCostEstimate(Pony player) { TypedActionResult amulet = getAmulet(player); @@ -74,8 +59,7 @@ public class UnicornCastingAbility implements Ability { return Math.min(manaLevel, ((AmuletItem)amulet.getValue().getItem()).getChargeRemainder(amulet.getValue())); } - Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND; - TypedActionResult> spell = player.getCharms().getSpellInHand(hand); + TypedActionResult> spell = player.getCharms().getSpellInHand(false); return !spell.getResult().isAccepted() || spell.getValue().isOn(player) ? 2 : 4; } @@ -87,13 +71,7 @@ public class UnicornCastingAbility implements Ability { return 0x000000; } - Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND; - TypedActionResult> newSpell = player.getCharms().getSpellInHand(hand); - - if (newSpell.getResult() != ActionResult.FAIL) { - return newSpell.getValue().type().getColor(); - } - return -1; + return super.getColor(player); } @Override @@ -118,8 +96,7 @@ public class UnicornCastingAbility implements Ability { } } } else { - Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND; - TypedActionResult> newSpell = player.getCharms().getSpellInHand(hand); + TypedActionResult> newSpell = player.getCharms().getSpellInHand(true); if (newSpell.getResult() != ActionResult.FAIL) { CustomisedSpellType spell = newSpell.getValue(); @@ -178,9 +155,4 @@ public class UnicornCastingAbility implements Ability { player.spawnParticles(MagicParticleEffect.UNICORN, 5); } } - - @Override - public void postApply(Pony player, AbilitySlot slot) { - player.spawnParticles(MagicParticleEffect.UNICORN, 5); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java index e0299d56..4f1bea80 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornDispellAbility.java @@ -43,7 +43,7 @@ public class UnicornDispellAbility implements Ability { } @Override - public Identifier getIcon(Pony player, boolean swap) { + public Identifier getIcon(Pony player) { Identifier id = Abilities.REGISTRY.getId(this); return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (player.getSpecies() == Race.CHANGELING ? "_changeling" : "") + ".png"); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java index 32261a02..ae02ec26 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornProjectileAbility.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.ability; -import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.ability.data.Hit; import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell; import com.minelittlepony.unicopia.ability.magic.spell.Spell; @@ -11,7 +10,6 @@ import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.util.TraceHelper; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; /** @@ -20,30 +18,15 @@ import net.minecraft.util.TypedActionResult; * 1. If the player is holding nothing, casts their equipped offensive spell (currently only vortex - inverse of shield) * 2. If the player is holding a gem, consumes it and casts whatever spell is contained within onto a projectile. */ -public class UnicornProjectileAbility implements Ability { +public class UnicornProjectileAbility extends AbstractSpellCastingAbility { @Override public int getWarmupTime(Pony player) { return 8; } - @Override - public int getCooldownTime(Pony player) { - return 0; - } - - @Override - public boolean canUse(Race race) { - return race.canCast(); - } - @Override public Hit tryActivate(Pony player) { - return Hit.of(player.getCharms().getSpellInHand(Hand.OFF_HAND).getResult() != ActionResult.FAIL); - } - - @Override - public Hit.Serializer getSerializer() { - return Hit.SERIALIZER; + return Hit.of(player.getCharms().getSpellInHand(false).getResult() != ActionResult.FAIL); } @Override @@ -55,8 +38,7 @@ public class UnicornProjectileAbility implements Ability { public boolean onQuickAction(Pony player, ActivationType type) { if (type == ActivationType.DOUBLE_TAP) { if (!player.isClient()) { - Hand hand = player.asEntity().isSneaking() ? Hand.MAIN_HAND : Hand.OFF_HAND; - TypedActionResult> thrown = player.getCharms().getSpellInHand(hand); + TypedActionResult> thrown = player.getCharms().getSpellInHand(true); if (thrown.getResult() != ActionResult.FAIL) { thrown.getValue().create().toThrowable().throwProjectile(player).ifPresent(projectile -> { @@ -73,8 +55,7 @@ public class UnicornProjectileAbility implements Ability { @Override public void apply(Pony player, Hit data) { - Hand hand = player.asEntity().isSneaking() ? Hand.MAIN_HAND : Hand.OFF_HAND; - TypedActionResult> thrown = player.getCharms().getSpellInHand(hand); + TypedActionResult> thrown = player.getCharms().getSpellInHand(true); if (thrown.getResult() != ActionResult.FAIL) { Spell spell = thrown.getValue().create(); @@ -96,9 +77,4 @@ public class UnicornProjectileAbility implements Ability { player.getMagicalReserves().getExhaustion().multiply(3.3F); player.spawnParticles(MagicParticleEffect.UNICORN, 5); } - - @Override - public void postApply(Pony player, AbilitySlot slot) { - player.spawnParticles(MagicParticleEffect.UNICORN, 5); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java index 4c3a33a4..3903d8e9 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java @@ -20,6 +20,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.sound.SoundCategory; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -31,9 +32,17 @@ import net.minecraft.world.World; public class UnicornTeleportAbility implements Ability { @Override - public Identifier getIcon(Pony player, boolean swap) { + public Identifier getIcon(Pony player) { Identifier id = Abilities.REGISTRY.getId(this); - return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (swap ? "_far" : "_near") + ".png"); + return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (player.asEntity().isSneaking() ? "_far" : "_near") + ".png"); + } + + @Override + public Text getName(Pony player) { + if (player.asEntity().isSneaking()) { + return Text.translatable(getTranslationKey() + ".far"); + } + return getName(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java b/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java index 9b9803db..b89dbff8 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java +++ b/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java @@ -8,7 +8,6 @@ import java.util.Set; import org.lwjgl.glfw.GLFW; import com.minelittlepony.unicopia.Unicopia; -import com.minelittlepony.unicopia.ability.Ability; import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilitySlot; import com.minelittlepony.unicopia.ability.ActivationType; @@ -87,7 +86,7 @@ public class KeyBindingsHandler { if (state != PressedState.UNCHANGED) { if (state == PressedState.PRESSED) { - abilities.activate(slot, page).map(Ability::getName).ifPresent(UHud.INSTANCE::setMessage); + abilities.activate(slot, page).map(a -> a.getName(iplayer)).ifPresent(UHud.INSTANCE::setMessage); } else { abilities.clear(slot, ActivationType.NONE, page); } diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java index f22e3f58..f57dd946 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -66,6 +66,10 @@ public class UHud extends DrawableHelper { @Nullable private LoopingSoundInstance partySound; + private boolean prevPointed; + private boolean prevReplacing; + private SpellType focusedType = SpellType.empty(); + public void render(InGameHud hud, MatrixStack matrices, float tickDelta) { if (client.player == null) { @@ -119,23 +123,29 @@ public class UHud extends DrawableHelper { slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta)); if (pony.getObservedSpecies().canCast()) { - - Ability ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY) + AbilitySlot slot = swap ? AbilitySlot.PASSIVE : AbilitySlot.PRIMARY; + Ability ability = pony.getAbilities().getStat(slot) .getAbility(Unicopia.getConfig().hudPage.get()) .orElse(null); if (ability == Abilities.CAST || ability == Abilities.SHOOT) { matrices.push(); matrices.translate(PRIMARY_SLOT_SIZE / 2F, PRIMARY_SLOT_SIZE / 2F, 0); - boolean first = ability == Abilities.CAST; - if (pony.asEntity().isSneaking()) { - first = !first; + boolean first = !pony.asEntity().isSneaking(); + TypedActionResult> inHand = pony.getCharms().getSpellInHand(false); + boolean replacing = inHand.getResult().isAccepted() && pony.getAbilities().getStat(slot).getActiveAbility().isEmpty(); + if (first != prevPointed || replacing != prevReplacing || inHand.getValue().type() != focusedType) { + focusedType = inHand.getValue().type(); + prevPointed = first; + prevReplacing = replacing; + setMessage(ability.getName(pony)); } matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(first ? 37 : 63)); matrices.translate(-23, 0, 0); matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-26)); matrices.scale(0.8F, 0.8F, 1); - UHud.drawTexture(matrices, 0, 0, 3, 120, 15, 7, 128, 128); + int u = replacing ? 16 : 3; + UHud.drawTexture(matrices, 0, 0, u, 120, 13, 7, 128, 128); matrices.pop(); } } @@ -327,8 +337,6 @@ public class UHud extends DrawableHelper { getZOffset(), Math.min(1, radius)); } - - public void setMessage(Text message) { this.message = message; this.messageTime = 60; @@ -342,7 +350,7 @@ public class UHud extends DrawableHelper { void renderAbilityIcon(MatrixStack matrices, AbilityDispatcher.Stat stat, int x, int y, int u, int v, int frameWidth, int frameHeight) { stat.getAbility(Unicopia.getConfig().hudPage.get()).ifPresent(ability -> { - RenderSystem.setShaderTexture(0, ability.getIcon(Pony.of(client.player), client.options.sneakKey.isPressed())); + RenderSystem.setShaderTexture(0, ability.getIcon(Pony.of(client.player))); drawTexture(matrices, x, y, 0, 0, frameWidth, frameHeight, u, v); RenderSystem.setShaderTexture(0, HUD_TEXTURE); }); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java index 0fadc54e..b01a9169 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookProfilePageContent.java @@ -34,7 +34,6 @@ public class SpellbookProfilePageContent extends DrawableHelper implements Spell int x = screen.getX() + bounds.left + bounds.width / 4 - size + 5; int y = screen.getY() + bounds.top + bounds.height / 2 + 3; - screen.addDrawable(new SpellbookScreen.ImageButton(x, y, size, size)) .getStyle() .setIcon(TribeButton.createSprite(pony.getActualSpecies(), 0, 0, size)) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCharmTracker.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCharmTracker.java index 2bdd554a..b720364b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCharmTracker.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCharmTracker.java @@ -34,10 +34,18 @@ public class PlayerCharmTracker implements NbtSerialisable { return handSpells[hand.ordinal()] == null ? SpellType.EMPTY_KEY.withTraits() : handSpells[hand.ordinal()]; } - public TypedActionResult> getSpellInHand(Hand hand) { + public Hand getHand() { + return pony.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND; + } + + public TypedActionResult> getSpellInHand(boolean consume) { + return getSpellInHand(getHand(), consume); + } + + public TypedActionResult> getSpellInHand(Hand hand, boolean consume) { return Streams.stream(pony.asEntity().getHandItems()) .filter(EnchantableItem::isEnchanted) - .map(stack -> EnchantableItem.consumeSpell(stack, pony.asEntity(), null)) + .map(stack -> EnchantableItem.consumeSpell(stack, pony.asEntity(), null, consume)) .findFirst() .orElse(getEquippedSpell(hand).toAction()); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java index b068fa0d..6ac2b43b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantableItem.java @@ -27,31 +27,34 @@ public interface EnchantableItem extends ItemConvertible { return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack)); } - static TypedActionResult> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate> filter) { + static TypedActionResult> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate> filter, boolean consume) { if (!isEnchanted(stack)) { - return TypedActionResult.pass(null); + return TypedActionResult.pass(SpellType.EMPTY_KEY.withTraits()); } SpellType key = EnchantableItem.getSpellKey(stack); if (key.isEmpty()) { - return TypedActionResult.fail(null); + return TypedActionResult.fail(SpellType.EMPTY_KEY.withTraits()); } CustomisedSpellType result = key.withTraits(SpellTraits.of(stack)); if (filter != null && !filter.test(result)) { - return TypedActionResult.fail(null); + return TypedActionResult.fail(SpellType.EMPTY_KEY.withTraits()); } - if (!player.world.isClient) { + if (!player.world.isClient && consume) { player.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND); + player.getItemCooldownManager().set(stack.getItem(), 20); - if (stack.getCount() == 1) { - unenchant(stack); - } else { - player.giveItemStack(unenchant(stack.split(1))); + if (!player.isCreative()) { + if (stack.getCount() == 1) { + unenchant(stack); + } else { + player.giveItemStack(unenchant(stack.split(1))); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java index 97d75a77..d9d127c1 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java @@ -44,7 +44,9 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem { return result; } - TypedActionResult> spell = EnchantableItem.consumeSpell(stack, user, ((Predicate>)charms.getEquippedSpell(hand)::equals).negate()); + hand = user.isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND; + + TypedActionResult> spell = EnchantableItem.consumeSpell(stack, user, ((Predicate>)charms.getEquippedSpell(hand)::equals).negate(), true); CustomisedSpellType existing = charms.getEquippedSpell(hand); @@ -67,6 +69,8 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem { charms.equipSpell(hand, SpellType.EMPTY_KEY.withTraits()); } + + user.getItemCooldownManager().set(this, 20); return TypedActionResult.success(stack, true); } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 8951a396..67cec935 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -326,11 +326,21 @@ "toxicity.severe.name": "Toxic", "toxicity.lethal.name": "Lethal", - "ability.unicopia.shoot": "Throw Magic", + "ability.unicopia.shoot": "Shoot Magic", + "ability.unicopia.shoot.with_spell": "Shoot %s", + "ability.unicopia.shoot.with_spell.active": "Shooting %s", + "ability.unicopia.shoot.with_spell.hand": "Shooting %s from hand", + "ability.unicopia.shoot.with_spell.replacing": "Replace %s with %s", "ability.unicopia.cast": "Cast Spell", + "ability.unicopia.cast.with_spell": "Cast %s", + "ability.unicopia.cast.with_spell.active": "Casting %s", + "ability.unicopia.cast.with_spell.hand": "Casting %s from hand", + "ability.unicopia.cast.with_spell.replacing": "Replace %s with %s", "ability.unicopia.dispell": "Dispell Magic", "ability.unicopia.teleport": "Teleport", + "ability.unicopia.teleport.far": "Teleport (Far)", "ability.unicopia.teleport_group": "Group Teleport", + "ability.unicopia.teleport_group.far": "Group Teleport (Far)", "ability.unicopia.grow": "Nourish Earth", "ability.unicopia.stomp": "Ground Pound", "ability.unicopia.kick": "Crushing Blow", diff --git a/src/main/resources/assets/unicopia/textures/gui/hud.png b/src/main/resources/assets/unicopia/textures/gui/hud.png index 97a2beeb..7070f5ad 100644 Binary files a/src/main/resources/assets/unicopia/textures/gui/hud.png and b/src/main/resources/assets/unicopia/textures/gui/hud.png differ