mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Make first/second/gem spell selection less confusing
- cast and shoot now both use the slot that's visually selected in the hud - swapping between first/second slot is done only by sneaking - there are now messages in the hud indicating the spell being cast - gems now have a cooldown after being used - holding a gem now changes the selector icon and title to make it clear that spells can be swapped - activating an ability whilst holding a gem changes the message to indicate you're casting the spell from the gem rather than your spell slot - ability titles now reflect what they do when sneaking - equipping a spell from a gem whilst in creative mode no longer consumes the gem's spell
This commit is contained in:
parent
a8e5c50e9b
commit
4202723731
16 changed files with 164 additions and 95 deletions
|
@ -91,17 +91,25 @@ public interface Ability<T extends Hit> {
|
||||||
/**
|
/**
|
||||||
* The icon representing this ability on the UI and HUD.
|
* 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);
|
Identifier id = Abilities.REGISTRY.getId(this);
|
||||||
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + ".png");
|
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Text getName(Pony player) {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The display name for this ability.
|
* The display name for this ability.
|
||||||
*/
|
*/
|
||||||
default Text getName() {
|
default Text getName() {
|
||||||
|
return Text.translatable(getTranslationKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getTranslationKey() {
|
||||||
Identifier id = Abilities.REGISTRY.getId(this);
|
Identifier id = Abilities.REGISTRY.getId(this);
|
||||||
return Text.translatable("ability." + id.getNamespace() + "." + id.getPath().replace('/', '.'));
|
return "ability." + id.getNamespace() + "." + id.getPath().replace('/', '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
package com.minelittlepony.unicopia.ability;
|
package com.minelittlepony.unicopia.ability;
|
||||||
|
|
||||||
public enum AbilitySlot {
|
public enum AbilitySlot {
|
||||||
|
/**
|
||||||
|
* No slot. Corresponds to abilities that are not equipped.
|
||||||
|
*/
|
||||||
NONE,
|
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,
|
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,
|
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,
|
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;
|
PASSIVE;
|
||||||
|
|
||||||
|
|
|
@ -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<Hit> {
|
||||||
|
|
||||||
|
@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<CustomisedSpellType<?>> 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<CustomisedSpellType<?>> newSpell = player.getCharms().getSpellInHand(false);
|
||||||
|
|
||||||
|
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||||
|
return newSpell.getValue().type().getColor();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hit.Serializer<Hit> getSerializer() {
|
||||||
|
return Hit.SERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postApply(Pony player, AbilitySlot slot) {
|
||||||
|
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ public class PegasusFlightToggleAbility implements Ability<Hit> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Identifier getIcon(Pony player, boolean swap) {
|
public Identifier getIcon(Pony player) {
|
||||||
Identifier id = Abilities.REGISTRY.getId(this);
|
Identifier id = Abilities.REGISTRY.getId(this);
|
||||||
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath()
|
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath()
|
||||||
+ (player.getPhysics().isFlying() ? "_land" : "_takeoff")
|
+ (player.getPhysics().isFlying() ? "_land" : "_takeoff")
|
||||||
|
|
|
@ -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.
|
* 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.
|
* 3. If the player is holding a amulet, charges it.
|
||||||
*/
|
*/
|
||||||
public class UnicornCastingAbility implements Ability<Hit> {
|
public class UnicornCastingAbility extends AbstractSpellCastingAbility {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWarmupTime(Pony player) {
|
public int getWarmupTime(Pony player) {
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCooldownTime(Pony player) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canUse(Race race) {
|
|
||||||
return race.canCast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Hit tryActivate(Pony player) {
|
public Hit tryActivate(Pony player) {
|
||||||
|
@ -59,11 +49,6 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
return Hit.of(player.getMagicalReserves().getMana().get() >= getCostEstimate(player));
|
return Hit.of(player.getMagicalReserves().getMana().get() >= getCostEstimate(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hit.Serializer<Hit> getSerializer() {
|
|
||||||
return Hit.SERIALIZER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getCostEstimate(Pony player) {
|
public double getCostEstimate(Pony player) {
|
||||||
TypedActionResult<ItemStack> amulet = getAmulet(player);
|
TypedActionResult<ItemStack> amulet = getAmulet(player);
|
||||||
|
@ -74,8 +59,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
return Math.min(manaLevel, ((AmuletItem)amulet.getValue().getItem()).getChargeRemainder(amulet.getValue()));
|
return Math.min(manaLevel, ((AmuletItem)amulet.getValue().getItem()).getChargeRemainder(amulet.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
TypedActionResult<CustomisedSpellType<?>> spell = player.getCharms().getSpellInHand(false);
|
||||||
TypedActionResult<CustomisedSpellType<?>> spell = player.getCharms().getSpellInHand(hand);
|
|
||||||
|
|
||||||
return !spell.getResult().isAccepted() || spell.getValue().isOn(player) ? 2 : 4;
|
return !spell.getResult().isAccepted() || spell.getValue().isOn(player) ? 2 : 4;
|
||||||
}
|
}
|
||||||
|
@ -87,13 +71,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
return 0x000000;
|
return 0x000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
return super.getColor(player);
|
||||||
TypedActionResult<CustomisedSpellType<?>> newSpell = player.getCharms().getSpellInHand(hand);
|
|
||||||
|
|
||||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
|
||||||
return newSpell.getValue().type().getColor();
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,8 +96,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Hand hand = player.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
TypedActionResult<CustomisedSpellType<?>> newSpell = player.getCharms().getSpellInHand(true);
|
||||||
TypedActionResult<CustomisedSpellType<?>> newSpell = player.getCharms().getSpellInHand(hand);
|
|
||||||
|
|
||||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||||
CustomisedSpellType<?> spell = newSpell.getValue();
|
CustomisedSpellType<?> spell = newSpell.getValue();
|
||||||
|
@ -178,9 +155,4 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postApply(Pony player, AbilitySlot slot) {
|
|
||||||
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class UnicornDispellAbility implements Ability<Pos> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Identifier getIcon(Pony player, boolean swap) {
|
public Identifier getIcon(Pony player) {
|
||||||
Identifier id = Abilities.REGISTRY.getId(this);
|
Identifier id = Abilities.REGISTRY.getId(this);
|
||||||
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (player.getSpecies() == Race.CHANGELING ? "_changeling" : "") + ".png");
|
return new Identifier(id.getNamespace(), "textures/gui/ability/" + id.getPath() + (player.getSpecies() == Race.CHANGELING ? "_changeling" : "") + ".png");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.ability;
|
package com.minelittlepony.unicopia.ability;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Race;
|
|
||||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
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 com.minelittlepony.unicopia.util.TraceHelper;
|
||||||
|
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
|
||||||
import net.minecraft.util.TypedActionResult;
|
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)
|
* 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.
|
* 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<Hit> {
|
public class UnicornProjectileAbility extends AbstractSpellCastingAbility {
|
||||||
@Override
|
@Override
|
||||||
public int getWarmupTime(Pony player) {
|
public int getWarmupTime(Pony player) {
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCooldownTime(Pony player) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canUse(Race race) {
|
|
||||||
return race.canCast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Hit tryActivate(Pony player) {
|
public Hit tryActivate(Pony player) {
|
||||||
return Hit.of(player.getCharms().getSpellInHand(Hand.OFF_HAND).getResult() != ActionResult.FAIL);
|
return Hit.of(player.getCharms().getSpellInHand(false).getResult() != ActionResult.FAIL);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hit.Serializer<Hit> getSerializer() {
|
|
||||||
return Hit.SERIALIZER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,8 +38,7 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
||||||
public boolean onQuickAction(Pony player, ActivationType type) {
|
public boolean onQuickAction(Pony player, ActivationType type) {
|
||||||
if (type == ActivationType.DOUBLE_TAP) {
|
if (type == ActivationType.DOUBLE_TAP) {
|
||||||
if (!player.isClient()) {
|
if (!player.isClient()) {
|
||||||
Hand hand = player.asEntity().isSneaking() ? Hand.MAIN_HAND : Hand.OFF_HAND;
|
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(true);
|
||||||
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(hand);
|
|
||||||
|
|
||||||
if (thrown.getResult() != ActionResult.FAIL) {
|
if (thrown.getResult() != ActionResult.FAIL) {
|
||||||
thrown.getValue().create().toThrowable().throwProjectile(player).ifPresent(projectile -> {
|
thrown.getValue().create().toThrowable().throwProjectile(player).ifPresent(projectile -> {
|
||||||
|
@ -73,8 +55,7 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Pony player, Hit data) {
|
public void apply(Pony player, Hit data) {
|
||||||
Hand hand = player.asEntity().isSneaking() ? Hand.MAIN_HAND : Hand.OFF_HAND;
|
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(true);
|
||||||
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(hand);
|
|
||||||
|
|
||||||
if (thrown.getResult() != ActionResult.FAIL) {
|
if (thrown.getResult() != ActionResult.FAIL) {
|
||||||
Spell spell = thrown.getValue().create();
|
Spell spell = thrown.getValue().create();
|
||||||
|
@ -96,9 +77,4 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
||||||
player.getMagicalReserves().getExhaustion().multiply(3.3F);
|
player.getMagicalReserves().getExhaustion().multiply(3.3F);
|
||||||
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postApply(Pony player, AbilitySlot slot) {
|
|
||||||
player.spawnParticles(MagicParticleEffect.UNICORN, 5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.predicate.entity.EntityPredicates;
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -31,9 +32,17 @@ import net.minecraft.world.World;
|
||||||
public class UnicornTeleportAbility implements Ability<Pos> {
|
public class UnicornTeleportAbility implements Ability<Pos> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Identifier getIcon(Pony player, boolean swap) {
|
public Identifier getIcon(Pony player) {
|
||||||
Identifier id = Abilities.REGISTRY.getId(this);
|
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
|
@Override
|
||||||
|
|
|
@ -8,7 +8,6 @@ import java.util.Set;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.Ability;
|
|
||||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||||
import com.minelittlepony.unicopia.ability.ActivationType;
|
import com.minelittlepony.unicopia.ability.ActivationType;
|
||||||
|
@ -87,7 +86,7 @@ public class KeyBindingsHandler {
|
||||||
|
|
||||||
if (state != PressedState.UNCHANGED) {
|
if (state != PressedState.UNCHANGED) {
|
||||||
if (state == PressedState.PRESSED) {
|
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 {
|
} else {
|
||||||
abilities.clear(slot, ActivationType.NONE, page);
|
abilities.clear(slot, ActivationType.NONE, page);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,10 @@ public class UHud extends DrawableHelper {
|
||||||
@Nullable
|
@Nullable
|
||||||
private LoopingSoundInstance<PlayerEntity> partySound;
|
private LoopingSoundInstance<PlayerEntity> partySound;
|
||||||
|
|
||||||
|
private boolean prevPointed;
|
||||||
|
private boolean prevReplacing;
|
||||||
|
private SpellType<?> focusedType = SpellType.empty();
|
||||||
|
|
||||||
public void render(InGameHud hud, MatrixStack matrices, float tickDelta) {
|
public void render(InGameHud hud, MatrixStack matrices, float tickDelta) {
|
||||||
|
|
||||||
if (client.player == null) {
|
if (client.player == null) {
|
||||||
|
@ -119,23 +123,29 @@ public class UHud extends DrawableHelper {
|
||||||
slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta));
|
slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta));
|
||||||
|
|
||||||
if (pony.getObservedSpecies().canCast()) {
|
if (pony.getObservedSpecies().canCast()) {
|
||||||
|
AbilitySlot slot = swap ? AbilitySlot.PASSIVE : AbilitySlot.PRIMARY;
|
||||||
Ability<?> ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY)
|
Ability<?> ability = pony.getAbilities().getStat(slot)
|
||||||
.getAbility(Unicopia.getConfig().hudPage.get())
|
.getAbility(Unicopia.getConfig().hudPage.get())
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
if (ability == Abilities.CAST || ability == Abilities.SHOOT) {
|
if (ability == Abilities.CAST || ability == Abilities.SHOOT) {
|
||||||
matrices.push();
|
matrices.push();
|
||||||
matrices.translate(PRIMARY_SLOT_SIZE / 2F, PRIMARY_SLOT_SIZE / 2F, 0);
|
matrices.translate(PRIMARY_SLOT_SIZE / 2F, PRIMARY_SLOT_SIZE / 2F, 0);
|
||||||
boolean first = ability == Abilities.CAST;
|
boolean first = !pony.asEntity().isSneaking();
|
||||||
if (pony.asEntity().isSneaking()) {
|
TypedActionResult<CustomisedSpellType<?>> inHand = pony.getCharms().getSpellInHand(false);
|
||||||
first = !first;
|
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.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(first ? 37 : 63));
|
||||||
matrices.translate(-23, 0, 0);
|
matrices.translate(-23, 0, 0);
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-26));
|
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-26));
|
||||||
matrices.scale(0.8F, 0.8F, 1);
|
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();
|
matrices.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,8 +337,6 @@ public class UHud extends DrawableHelper {
|
||||||
getZOffset(), Math.min(1, radius));
|
getZOffset(), Math.min(1, radius));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void setMessage(Text message) {
|
public void setMessage(Text message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.messageTime = 60;
|
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) {
|
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 -> {
|
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);
|
drawTexture(matrices, x, y, 0, 0, frameWidth, frameHeight, u, v);
|
||||||
RenderSystem.setShaderTexture(0, HUD_TEXTURE);
|
RenderSystem.setShaderTexture(0, HUD_TEXTURE);
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,6 @@ public class SpellbookProfilePageContent extends DrawableHelper implements Spell
|
||||||
int x = screen.getX() + bounds.left + bounds.width / 4 - size + 5;
|
int x = screen.getX() + bounds.left + bounds.width / 4 - size + 5;
|
||||||
int y = screen.getY() + bounds.top + bounds.height / 2 + 3;
|
int y = screen.getY() + bounds.top + bounds.height / 2 + 3;
|
||||||
|
|
||||||
|
|
||||||
screen.addDrawable(new SpellbookScreen.ImageButton(x, y, size, size))
|
screen.addDrawable(new SpellbookScreen.ImageButton(x, y, size, size))
|
||||||
.getStyle()
|
.getStyle()
|
||||||
.setIcon(TribeButton.createSprite(pony.getActualSpecies(), 0, 0, size))
|
.setIcon(TribeButton.createSprite(pony.getActualSpecies(), 0, 0, size))
|
||||||
|
|
|
@ -34,10 +34,18 @@ public class PlayerCharmTracker implements NbtSerialisable {
|
||||||
return handSpells[hand.ordinal()] == null ? SpellType.EMPTY_KEY.withTraits() : handSpells[hand.ordinal()];
|
return handSpells[hand.ordinal()] == null ? SpellType.EMPTY_KEY.withTraits() : handSpells[hand.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(Hand hand) {
|
public Hand getHand() {
|
||||||
|
return pony.asEntity().isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(boolean consume) {
|
||||||
|
return getSpellInHand(getHand(), consume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(Hand hand, boolean consume) {
|
||||||
return Streams.stream(pony.asEntity().getHandItems())
|
return Streams.stream(pony.asEntity().getHandItems())
|
||||||
.filter(EnchantableItem::isEnchanted)
|
.filter(EnchantableItem::isEnchanted)
|
||||||
.map(stack -> EnchantableItem.consumeSpell(stack, pony.asEntity(), null))
|
.map(stack -> EnchantableItem.consumeSpell(stack, pony.asEntity(), null, consume))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(getEquippedSpell(hand).toAction());
|
.orElse(getEquippedSpell(hand).toAction());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,33 +27,36 @@ public interface EnchantableItem extends ItemConvertible {
|
||||||
return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack));
|
return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate<CustomisedSpellType<?>> filter) {
|
static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate<CustomisedSpellType<?>> filter, boolean consume) {
|
||||||
|
|
||||||
if (!isEnchanted(stack)) {
|
if (!isEnchanted(stack)) {
|
||||||
return TypedActionResult.pass(null);
|
return TypedActionResult.pass(SpellType.EMPTY_KEY.withTraits());
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellType<Spell> key = EnchantableItem.getSpellKey(stack);
|
SpellType<Spell> key = EnchantableItem.getSpellKey(stack);
|
||||||
|
|
||||||
if (key.isEmpty()) {
|
if (key.isEmpty()) {
|
||||||
return TypedActionResult.fail(null);
|
return TypedActionResult.fail(SpellType.EMPTY_KEY.withTraits());
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomisedSpellType<?> result = key.withTraits(SpellTraits.of(stack));
|
CustomisedSpellType<?> result = key.withTraits(SpellTraits.of(stack));
|
||||||
|
|
||||||
if (filter != null && !filter.test(result)) {
|
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.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND);
|
||||||
|
player.getItemCooldownManager().set(stack.getItem(), 20);
|
||||||
|
|
||||||
|
if (!player.isCreative()) {
|
||||||
if (stack.getCount() == 1) {
|
if (stack.getCount() == 1) {
|
||||||
unenchant(stack);
|
unenchant(stack);
|
||||||
} else {
|
} else {
|
||||||
player.giveItemStack(unenchant(stack.split(1)));
|
player.giveItemStack(unenchant(stack.split(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TypedActionResult.consume(result);
|
return TypedActionResult.consume(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,9 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedActionResult<CustomisedSpellType<?>> spell = EnchantableItem.consumeSpell(stack, user, ((Predicate<CustomisedSpellType<?>>)charms.getEquippedSpell(hand)::equals).negate());
|
hand = user.isSneaking() ? Hand.OFF_HAND : Hand.MAIN_HAND;
|
||||||
|
|
||||||
|
TypedActionResult<CustomisedSpellType<?>> spell = EnchantableItem.consumeSpell(stack, user, ((Predicate<CustomisedSpellType<?>>)charms.getEquippedSpell(hand)::equals).negate(), true);
|
||||||
|
|
||||||
CustomisedSpellType<?> existing = charms.getEquippedSpell(hand);
|
CustomisedSpellType<?> existing = charms.getEquippedSpell(hand);
|
||||||
|
|
||||||
|
@ -67,6 +69,8 @@ public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
||||||
|
|
||||||
charms.equipSpell(hand, SpellType.EMPTY_KEY.withTraits());
|
charms.equipSpell(hand, SpellType.EMPTY_KEY.withTraits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.getItemCooldownManager().set(this, 20);
|
||||||
return TypedActionResult.success(stack, true);
|
return TypedActionResult.success(stack, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -326,11 +326,21 @@
|
||||||
"toxicity.severe.name": "Toxic",
|
"toxicity.severe.name": "Toxic",
|
||||||
"toxicity.lethal.name": "Lethal",
|
"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": "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.dispell": "Dispell Magic",
|
||||||
"ability.unicopia.teleport": "Teleport",
|
"ability.unicopia.teleport": "Teleport",
|
||||||
|
"ability.unicopia.teleport.far": "Teleport (Far)",
|
||||||
"ability.unicopia.teleport_group": "Group Teleport",
|
"ability.unicopia.teleport_group": "Group Teleport",
|
||||||
|
"ability.unicopia.teleport_group.far": "Group Teleport (Far)",
|
||||||
"ability.unicopia.grow": "Nourish Earth",
|
"ability.unicopia.grow": "Nourish Earth",
|
||||||
"ability.unicopia.stomp": "Ground Pound",
|
"ability.unicopia.stomp": "Ground Pound",
|
||||||
"ability.unicopia.kick": "Crushing Blow",
|
"ability.unicopia.kick": "Crushing Blow",
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Loading…
Reference in a new issue