diff --git a/src/main/java/com/minelittlepony/unicopia/Config.java b/src/main/java/com/minelittlepony/unicopia/Config.java index 8ccae93c..af798840 100644 --- a/src/main/java/com/minelittlepony/unicopia/Config.java +++ b/src/main/java/com/minelittlepony/unicopia/Config.java @@ -34,6 +34,9 @@ public class Config extends com.minelittlepony.common.util.settings.Config { .addComment("If true Mine Little Pony will not be considered when determining the race to use") .addComment("The result will always be what is set by this config file."); + public final Setting toggleAbilityKeys = value("client", "toggleAbilityKeys", false) + .addComment("If true the ability keybinds will function as toggle keys rather than hold keys"); + public final Setting hudPage = value("client", "hudActivePage", 0) .addComment("The page of abilities currently visible in the HUD. You can change this in-game using the PG_UP and PG_DWN keys (configurable)"); diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index 9e06f047..c3ab492d 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -73,7 +73,7 @@ public record Race ( .abilities(Abilities.HUG, Abilities.STOMP, Abilities.KICK, Abilities.GROW) ); public static final Race UNICORN = register("unicorn", new Builder().foraging().magic() - .abilities(Abilities.TELEPORT, Abilities.GROUP_TELEPORT, Abilities.SHOOT, Abilities.DISPELL) + .abilities(Abilities.TELEPORT, Abilities.CAST, Abilities.GROUP_TELEPORT, Abilities.SHOOT, Abilities.DISPELL) ); public static final Race PEGASUS = register("pegasus", new Builder().foraging().flight(FlightType.AVIAN).weatherMagic().cloudMagic() .abilities(Abilities.TOGGLE_FLIGHT, Abilities.RAINBOOM, Abilities.CAPTURE_CLOUD, Abilities.CARRY) @@ -83,7 +83,7 @@ public record Race ( ); public static final Race ALICORN = register("alicorn", new Builder().foraging().availability(Availability.COMMANDS).flight(FlightType.AVIAN).earth().magic().weatherMagic().cloudMagic() .abilities( - Abilities.TELEPORT, Abilities.GROUP_TELEPORT, Abilities.SHOOT, Abilities.DISPELL, + Abilities.TELEPORT, Abilities.GROUP_TELEPORT, Abilities.CAST, Abilities.SHOOT, Abilities.DISPELL, Abilities.TOGGLE_FLIGHT, Abilities.RAINBOOM, Abilities.CAPTURE_CLOUD, Abilities.CARRY, Abilities.HUG, Abilities.STOMP, Abilities.KICK, Abilities.GROW, Abilities.TIME diff --git a/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java b/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java index d8c52062..23494849 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java +++ b/src/main/java/com/minelittlepony/unicopia/client/KeyBindingsHandler.java @@ -18,7 +18,9 @@ import com.minelittlepony.unicopia.entity.player.Pony; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.option.StickyKeyBinding; import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.InputUtil; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; @@ -35,6 +37,10 @@ public class KeyBindingsHandler { private final Binding pageDown = register(GLFW.GLFW_KEY_PAGE_DOWN, "hud_page_dn"); private final Binding pageUp = register(GLFW.GLFW_KEY_PAGE_UP, "hud_page_up"); + private final Binding singleTapModifier = register(InputUtil.UNKNOWN_KEY.getCode(), "ability_modifier_tap"); + private final Binding doubleTapModifier = register(InputUtil.UNKNOWN_KEY.getCode(), "ability_modifier_double_tap"); + private final Binding tripleTapModifier = register(InputUtil.UNKNOWN_KEY.getCode(), "ability_modifier_triple_tap"); + private final Set pressed = new HashSet<>(); public KeyBindingsHandler() { @@ -47,8 +53,12 @@ public class KeyBindingsHandler { return reverse.get(slot); } + public boolean isToggleMode() { + return Unicopia.getConfig().toggleAbilityKeys.get(); + } + public void addKeybind(int code, AbilitySlot slot) { - Binding binding = register(code, slot.name().toLowerCase()); + Binding binding = new Binding(KeyBindingHelper.registerKeyBinding(new StickyKeyBinding("key.unicopia." + slot.name().toLowerCase(), code, KEY_CATEGORY, this::isToggleMode))); reverse.put(slot, binding); keys.put(binding, slot); } @@ -104,6 +114,7 @@ public class KeyBindingsHandler { int page = Unicopia.getConfig().hudPage.get(); page += sigma; Unicopia.getConfig().hudPage.set(page); + Unicopia.getConfig().save(); client.getSoundManager().play(PositionedSoundInstance.master(USounds.Vanilla.UI_BUTTON_CLICK, 1.75F + (0.25F * sigma))); UHud.INSTANCE.setMessage(Text.translatable("gui.unicopia.page_num", page + 1, max + 1)); } @@ -141,6 +152,27 @@ public class KeyBindingsHandler { } public ActivationType getType() { + if (binding.isPressed() && binding instanceof StickyKeyBinding) { + if (singleTapModifier.binding.isPressed()) { + KeyBinding.untoggleStickyKeys(); + return ActivationType.TAP; + } + + if (doubleTapModifier.binding.isPressed()) { + KeyBinding.untoggleStickyKeys(); + return ActivationType.DOUBLE_TAP; + } + + if (tripleTapModifier.binding.isPressed()) { + KeyBinding.untoggleStickyKeys(); + return ActivationType.TRIPLE_TAP; + } + + if (isToggleMode()) { + return ActivationType.NONE; + } + } + long now = System.currentTimeMillis(); if (type != ActivationType.NONE && now > nextPhaseTime - 70) { ActivationType t = type; diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/SettingsScreen.java b/src/main/java/com/minelittlepony/unicopia/client/gui/SettingsScreen.java index 749d2b13..4d0d5452 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/SettingsScreen.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/SettingsScreen.java @@ -68,6 +68,10 @@ public class SettingsScreen extends GameGui { }) .getStyle().setText("unicopia.options.ignore_mine_lp"); + content.addButton(new Toggle(LEFT, row += 20, config.toggleAbilityKeys.get())) + .onChange(config.toggleAbilityKeys) + .getStyle().setText("unicopia.options.toggle_ability_keys"); + mineLpStatus = content.addButton(new Label(LEFT, row += 10)).getStyle().setText(getMineLPStatus()); RegistryIndexer races = RegistryIndexer.of(Race.REGISTRY); diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/Slot.java b/src/main/java/com/minelittlepony/unicopia/client/gui/Slot.java index 4117c7e1..434f5dda 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/Slot.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/Slot.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.client.gui; +import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.AbilityDispatcher; import com.minelittlepony.unicopia.ability.AbilitySlot; import com.minelittlepony.unicopia.client.KeyBindingsHandler; @@ -82,6 +83,12 @@ class Slot { bSwap &= abilities.isFilled(bSlot); } + AbilityDispatcher.Stat stat = abilities.getStat(bSwap ? bSlot : aSlot); + + if (stat.getAbility(Unicopia.getConfig().hudPage.get()).isEmpty()) { + return; + } + RenderSystem.setShaderColor(1, 1, 1, 1); RenderSystem.enableBlend(); MatrixStack matrices = context.getMatrices(); @@ -91,7 +98,7 @@ class Slot { // background context.drawTexture(UHud.HUD_TEXTURE, 0, 0, backgroundU, backgroundV, size, size, 128, 128); - AbilityDispatcher.Stat stat = abilities.getStat(bSwap ? bSlot : aSlot); + int iconPosition = ((size - iconSize + slotPadding + 1) / 2); int sz = iconSize - slotPadding; @@ -122,6 +129,11 @@ class Slot { } void renderLabel(DrawContext context, AbilityDispatcher abilities, float tickDelta) { + + if (abilities.getStat(aSlot).getAbility(Unicopia.getConfig().hudPage.get()).isEmpty()) { + return; + } + Text label = KeyBindingsHandler.INSTANCE.getBinding(aSlot).getLabel(); MatrixStack matrices = context.getMatrices(); 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 11a5bf02..59b89037 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/UHud.java @@ -48,8 +48,8 @@ public class UHud { private final List slots = List.of( new ManaRingSlot(this, AbilitySlot.PRIMARY, AbilitySlot.PASSIVE, 0, 0), - new Slot(this, AbilitySlot.SECONDARY, AbilitySlot.SECONDARY, 26, -5), - new Slot(this, AbilitySlot.TERTIARY, AbilitySlot.TERTIARY, 36, 19) + new Slot(this, AbilitySlot.SECONDARY, AbilitySlot.SECONDARY, 30, -8), + new Slot(this, AbilitySlot.TERTIARY, AbilitySlot.TERTIARY, 40, 18) ); @Nullable @@ -68,10 +68,6 @@ public class UHud { private SpellType focusedType = SpellType.empty(); public void render(InGameHud hud, DrawContext context, float tickDelta) { - - // TODO: Check this when backporting! - // InGameHud#renderHotbar line 460 - // context.getMatrices().translate(0.0f, 0.0f, -90.0f); final int hotbarZ = -90; if (client.player == null) { @@ -96,7 +92,6 @@ public class UHud { font = client.textRenderer; xDirection = client.player.getMainArm() == Arm.LEFT ? -1 : 1; - matrices.push(); matrices.translate(scaledWidth / 2, scaledHeight / 2, 0); @@ -109,7 +104,7 @@ public class UHud { matrices.pop(); matrices.push(); - int hudX = ((scaledWidth - 50) / 2) + (104 * xDirection); + int hudX = ((scaledWidth - 50) / 2) + (109 * xDirection); int hudY = scaledHeight - 50; int hudZ = hotbarZ; @@ -139,33 +134,33 @@ public class UHud { slots.forEach(slot -> slot.renderBackground(context, abilities, swap, tickDelta)); - boolean canCast = Abilities.CAST.canUse(pony.getCompositeRace()) || Abilities.KIRIN_CAST.canUse(pony.getCompositeRace()); + + Ability ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY) + .getAbility(Unicopia.getConfig().hudPage.get()) + .orElse(null); + boolean canCast = ability == Abilities.CAST || ability == Abilities.KIRIN_CAST || ability == Abilities.SHOOT; if (canCast) { - Ability ability = pony.getAbilities().getStat(AbilitySlot.PRIMARY) - .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 = !pony.asEntity().isSneaking(); - TypedActionResult> inHand = pony.getCharms().getSpellInHand(false); - boolean replacing = inHand.getResult().isAccepted() && pony.getAbilities().getStat(AbilitySlot.PRIMARY).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); - int u = replacing ? 16 : 3; - context.drawTexture(HUD_TEXTURE, 0, 0, u, 120, 13, 7, 128, 128); - matrices.pop(); + matrices.push(); + matrices.translate(PRIMARY_SLOT_SIZE / 2F, PRIMARY_SLOT_SIZE / 2F, 0); + boolean first = !pony.asEntity().isSneaking(); + TypedActionResult> inHand = pony.getCharms().getSpellInHand(false); + boolean replacing = inHand.getResult().isAccepted() && pony.getAbilities().getStat(AbilitySlot.PRIMARY).getActiveAbility().isEmpty(); + if (first != prevPointed || replacing != prevReplacing || inHand.getValue().type() != focusedType) { + focusedType = inHand.getValue().type(); + prevPointed = first; + prevReplacing = replacing; + setMessage(ability.getName(pony)); } + int baseAngle = xDirection < 0 ? 100 : 0; + int secondAngleDif = xDirection * 30; + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(baseAngle + 37 + (first ? 0 : secondAngleDif))); + matrices.translate(-23, 0, 0); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-26)); + matrices.scale(0.8F, 0.8F, 1); + int u = replacing ? 16 : 3; + context.drawTexture(HUD_TEXTURE, 0, 0, u, 120, 13, 7, 128, 128); + matrices.pop(); } slots.forEach(slot -> slot.renderLabel(context, abilities, tickDelta)); @@ -173,8 +168,13 @@ public class UHud { matrices.pop(); if (canCast) { + matrices.push(); + if (xDirection < 0) { + hudX += PRIMARY_SLOT_SIZE / 2F - 8; + } SpellIconRenderer.renderSpell(context, pony.getCharms().getEquippedSpell(Hand.MAIN_HAND), hudX + 10 - xDirection * 13, hudY + 2, EQUIPPED_GEMSTONE_SCALE); SpellIconRenderer.renderSpell(context, pony.getCharms().getEquippedSpell(Hand.OFF_HAND), hudX + 8 - xDirection * 2, hudY - 6, EQUIPPED_GEMSTONE_SCALE); + matrices.pop(); } RenderSystem.disableBlend(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java index 6a0731b4..ceaf6dad 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.USounds; -import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.item.ButterflyItem; import com.minelittlepony.unicopia.util.NbtSerialisable; @@ -74,7 +73,7 @@ public class ButterflyEntity extends AmbientEntity { } public static boolean canSpawn(EntityType type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { - return world.getBlockState(pos.down()).isIn(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON); + return true;//world.getBlockState(pos.down()).isIn(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java index 8d6ea782..76b0de8a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java @@ -26,7 +26,8 @@ import net.minecraft.world.Heightmap.Type; public interface UEntities { EntityType BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.AMBIENT).entityFactory(ButterflyEntity::new) - .spawnRestriction(Location.NO_RESTRICTIONS, Type.WORLD_SURFACE_WG, ButterflyEntity::canSpawn) + .spawnRestriction(Location.NO_RESTRICTIONS, Type.MOTION_BLOCKING_NO_LEAVES, ButterflyEntity::canSpawn) + .spawnableFarFromPlayer() .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.create(SpawnGroup.MISC, MagicProjectileEntity::new) .trackRangeBlocks(100) @@ -83,7 +84,7 @@ public interface UEntities { .trackRangeChunks(8) .dimensions(EntityDimensions.fixed(3, 2))); EntityType SPECTER = register("specter", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.MONSTER).entityFactory(SpecterEntity::new) - .spawnRestriction(Location.ON_GROUND, Type.WORLD_SURFACE, HostileEntity::canSpawnInDark) + .spawnRestriction(Location.ON_GROUND, Type.MOTION_BLOCKING_NO_LEAVES, HostileEntity::canSpawnIgnoreLightLevel) .fireImmune() .spawnableFarFromPlayer() .dimensions(EntityDimensions.fixed(1, 2))); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 736626b1..523ff40e 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1329,6 +1329,9 @@ "key.unicopia.secondary": "Secondary Ability", "key.unicopia.tertiary": "Tertiary Ability", "key.unicopia.passive": "Passive Ability", + "key.unicopia.ability_modifier_tap": "VR Ability Modifier (1-TAP)", + "key.unicopia.ability_modifier_double_tap": "VR Ability Modifier (2-TAP)", + "key.unicopia.ability_modifier_triple_tap": "VR Ability Modifier (3-TAP)", "key.unicopia.hud_page_dn": "Hud Previous Page", "key.unicopia.hud_page_up": "Hud Next Page", @@ -1408,6 +1411,7 @@ "commands.gravity.set.multiple": "Updated %s entities", "unicopia.options.title": "Unicopia Options", + "unicopia.options.toggle_ability_keys": "Sticky Ability Keys", "unicopia.options.ignore_mine_lp": "Ignore Mine Little Pony", "unicopia.options.ignore_mine_lp.missing": "* Mine Little Pony is not installed", "unicopia.options.ignore_mine_lp.detected": "* Your detected race is %s", @@ -1427,28 +1431,28 @@ "command.unicopia.config.list": "[Config] Property (%s) contains (%s) entries: ", "command.unicopia.config.clear": "[Config] Cleared all values from property %s", - "unicopia.race.unset": "Unset", - "unicopia.race.unset.alt": "Unset", - "unicopia.race.human": "Human", - "unicopia.race.human.alt": "Humans", - "unicopia.race.earth": "Earth Pony", - "unicopia.race.earth.alt": "Earth Ponies", - "unicopia.race.unicorn": "Unicorn", - "unicopia.race.unicorn.alt": "Unicorns", - "unicopia.race.pegasus": "Pegasus", - "unicopia.race.pegasus.alt": "Pegasi", - "unicopia.race.alicorn": "Alicorn", - "unicopia.race.alicorn.alt": "Alicorns", - "unicopia.race.changeling": "Changeling", - "unicopia.race.changeling.alt": "Changelings", - "unicopia.race.bat": "Bat Pony", - "unicopia.race.bat.alt": "Bat Ponies", - "unicopia.race.kirin": "Kirin", - "unicopia.race.kirin.alt": "Kirins", - "unicopia.race.hippogriff": "Hippogriff", - "unicopia.race.hippogriff.alt": "Hippogriffs", - "unicopia.race.seapony": "Sea Pony", - "unicopia.race.seapony.alt": "Sea Ponies", + "race.unicopia.unset": "Unset", + "race.unicopia.unset.alt": "Unset", + "race.unicopia.human": "Human", + "race.unicopia.human.alt": "Humans", + "race.unicopia.earth": "Earth Pony", + "race.unicopia.earth.alt": "Earth Ponies", + "race.unicopia.unicorn": "Unicorn", + "race.unicopia.unicorn.alt": "Unicorns", + "race.unicopia.pegasus": "Pegasus", + "race.unicopia.pegasus.alt": "Pegasi", + "race.unicopia.alicorn": "Alicorn", + "race.unicopia.alicorn.alt": "Alicorns", + "race.unicopia.changeling": "Changeling", + "race.unicopia.changeling.alt": "Changelings", + "race.unicopia.bat": "Bat Pony", + "race.unicopia.bat.alt": "Bat Ponies", + "race.unicopia.kirin": "Kirin", + "race.unicopia.kirin.alt": "Kirins", + "race.unicopia.hippogriff": "Hippogriff", + "race.unicopia.hippogriff.alt": "Hippogriffs", + "race.unicopia.seapony": "Sea Pony", + "race.unicopia.seapony.alt": "Sea Ponies", "death.attack.unicopia.generic.and_also": "%1$s and %2$s", "death.attack.unicopia.generic.whilst_flying": "%1$s whilst flying",