mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47:59 +01:00
Added paging to the HUD so abilities don't have to be exclusive
This commit is contained in:
parent
4d8c41fa8b
commit
cef123e162
5 changed files with 133 additions and 19 deletions
|
@ -5,6 +5,8 @@ import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
@ -22,6 +24,10 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
||||||
|
|
||||||
private final Map<AbilitySlot, Stat> stats = new EnumMap<>(AbilitySlot.class);
|
private final Map<AbilitySlot, Stat> stats = new EnumMap<>(AbilitySlot.class);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Race prevRace;
|
||||||
|
private long maxPage;
|
||||||
|
|
||||||
public AbilityDispatcher(Pony player) {
|
public AbilityDispatcher(Pony player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
@ -34,10 +40,10 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void activate(AbilitySlot slot) {
|
public void activate(AbilitySlot slot, long page) {
|
||||||
Stat stat = getStat(slot);
|
Stat stat = getStat(slot);
|
||||||
if (stat.canSwitchStates()) {
|
if (stat.canSwitchStates()) {
|
||||||
stat.getAbility().ifPresent(stat::setActiveAbility);
|
stat.getAbility(page).ifPresent(stat::setActiveAbility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +51,14 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
||||||
return stats.computeIfAbsent(slot, Stat::new);
|
return stats.computeIfAbsent(slot, Stat::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getMaxPage() {
|
||||||
|
if (prevRace != player.getSpecies()) {
|
||||||
|
prevRace = player.getSpecies();
|
||||||
|
maxPage = Math.max(0, stats.values().stream().mapToLong(Stat::getMaxPage).reduce(0, Math::max) - 1);
|
||||||
|
}
|
||||||
|
return maxPage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
stats.values().forEach(Stat::tick);
|
stats.values().forEach(Stat::tick);
|
||||||
|
@ -176,14 +190,23 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Ability<?>> getAbility() {
|
public Optional<Ability<?>> getAbility(long page) {
|
||||||
Race race = player.getSpecies();
|
Race race = player.getSpecies();
|
||||||
return Abilities.BY_SLOT.computeIfAbsent(slot, c -> Collections.emptySet())
|
return Abilities.BY_SLOT.computeIfAbsent(slot, c -> Collections.emptySet())
|
||||||
.stream()
|
.stream()
|
||||||
.filter(a -> a.canUse(race))
|
.filter(a -> a.canUse(race))
|
||||||
|
.skip(page)
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getMaxPage() {
|
||||||
|
Race race = player.getSpecies();
|
||||||
|
return Abilities.BY_SLOT.computeIfAbsent(slot, c -> Collections.emptySet())
|
||||||
|
.stream()
|
||||||
|
.filter(a -> a.canUse(race))
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void setActiveAbility(Ability<?> power) {
|
protected synchronized void setActiveAbility(Ability<?> power) {
|
||||||
if (activeAbility.orElse(null) != power) {
|
if (activeAbility.orElse(null) != power) {
|
||||||
triggered = false;
|
triggered = false;
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class EarthPonyGrowAbility implements Ability<Pos> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canUse(Race race) {
|
public boolean canUse(Race race) {
|
||||||
return race == Race.EARTH;
|
return race.canUseEarth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,15 +7,21 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||||
|
import com.minelittlepony.unicopia.client.gui.UHud;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.options.KeyBinding;
|
import net.minecraft.client.options.KeyBinding;
|
||||||
|
import net.minecraft.client.sound.PositionedSoundInstance;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public class KeyBindingsHandler {
|
public class KeyBindingsHandler {
|
||||||
private final String KEY_CATEGORY = "unicopia.category.name";
|
private static final String KEY_CATEGORY = "unicopia.category.name";
|
||||||
|
|
||||||
public static final KeyBindingsHandler INSTANCE = new KeyBindingsHandler();
|
public static final KeyBindingsHandler INSTANCE = new KeyBindingsHandler();
|
||||||
|
|
||||||
|
@ -24,6 +30,11 @@ public class KeyBindingsHandler {
|
||||||
private final Map<KeyBinding, AbilitySlot> keys = new HashMap<>();
|
private final Map<KeyBinding, AbilitySlot> keys = new HashMap<>();
|
||||||
private final Map<AbilitySlot, KeyBinding> reverse = new HashMap<>();
|
private final Map<AbilitySlot, KeyBinding> reverse = new HashMap<>();
|
||||||
|
|
||||||
|
private final KeyBinding pageDown = register(GLFW.GLFW_KEY_PAGE_DOWN, "hud_page_dn");
|
||||||
|
private final KeyBinding pageUp = register(GLFW.GLFW_KEY_PAGE_UP, "hud_page_up");
|
||||||
|
|
||||||
|
public long page = 0;
|
||||||
|
|
||||||
private final Set<KeyBinding> pressed = new HashSet<>();
|
private final Set<KeyBinding> pressed = new HashSet<>();
|
||||||
|
|
||||||
public KeyBindingsHandler() {
|
public KeyBindingsHandler() {
|
||||||
|
@ -37,31 +48,69 @@ public class KeyBindingsHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addKeybind(int code, AbilitySlot slot) {
|
public void addKeybind(int code, AbilitySlot slot) {
|
||||||
KeyBinding binding = KeyBindingHelper.registerKeyBinding(new KeyBinding("key.unicopia." + slot.name().toLowerCase(), code, KEY_CATEGORY));
|
KeyBinding binding = register(code, slot.name().toLowerCase());
|
||||||
reverse.put(slot, binding);
|
reverse.put(slot, binding);
|
||||||
keys.put(binding, slot);
|
keys.put(binding, slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static KeyBinding register(int code, String name) {
|
||||||
|
return KeyBindingHelper.registerKeyBinding(new KeyBinding("key.unicopia." + name, code, KEY_CATEGORY));
|
||||||
|
}
|
||||||
|
|
||||||
public void tick(MinecraftClient client) {
|
public void tick(MinecraftClient client) {
|
||||||
if (client.currentScreen != null
|
if (client.currentScreen != null
|
||||||
|| client.player == null) {
|
|| client.player == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Pony iplayer = Pony.of(client.player);
|
Pony iplayer = Pony.of(client.player);
|
||||||
|
AbilityDispatcher abilities = iplayer.getAbilities();
|
||||||
|
long maxPage = abilities.getMaxPage();
|
||||||
|
|
||||||
|
page = MathHelper.clamp(page, 0, maxPage);
|
||||||
|
|
||||||
|
if (page > 0 && checkPressed(pageDown) == PressedState.PRESSED) {
|
||||||
|
changePage(client, maxPage, -1);
|
||||||
|
} else if (page < maxPage && checkPressed(pageUp) == PressedState.PRESSED) {
|
||||||
|
changePage(client, maxPage, 1);
|
||||||
|
} else {
|
||||||
for (KeyBinding i : keys.keySet()) {
|
for (KeyBinding i : keys.keySet()) {
|
||||||
AbilitySlot slot = keys.get(i);
|
AbilitySlot slot = keys.get(i);
|
||||||
if (slot == AbilitySlot.PRIMARY && client.options.keySneak.isPressed()) {
|
if (slot == AbilitySlot.PRIMARY && client.options.keySneak.isPressed()) {
|
||||||
slot = AbilitySlot.PASSIVE;
|
slot = AbilitySlot.PASSIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.isPressed()) {
|
PressedState state = checkPressed(i);
|
||||||
if (pressed.add(i)) {
|
if (state != PressedState.UNCHANGED) {
|
||||||
iplayer.getAbilities().activate(slot);
|
if (state == PressedState.PRESSED) {
|
||||||
}
|
abilities.activate(slot, page);
|
||||||
} else if (pressed.remove(i)) {
|
} else {
|
||||||
iplayer.getAbilities().clear(slot);
|
abilities.clear(slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changePage(MinecraftClient client, long max, int sigma) {
|
||||||
|
page += sigma;
|
||||||
|
client.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.75F + (0.25F * sigma)));
|
||||||
|
UHud.instance.setMessage(new LiteralText(page + " of " + max));
|
||||||
|
}
|
||||||
|
|
||||||
|
private PressedState checkPressed(KeyBinding binding) {
|
||||||
|
if (binding.isPressed()) {
|
||||||
|
return pressed.add(binding) ? PressedState.PRESSED : PressedState.UNCHANGED;
|
||||||
|
} else if (pressed.remove(binding)) {
|
||||||
|
return PressedState.UNPRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return PressedState.UNCHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PressedState {
|
||||||
|
UNCHANGED,
|
||||||
|
PRESSED,
|
||||||
|
UNPRESSED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.minelittlepony.common.event.ScreenInitCallback.ButtonList;
|
||||||
import com.minelittlepony.unicopia.InteractionManager;
|
import com.minelittlepony.unicopia.InteractionManager;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
|
import com.minelittlepony.unicopia.client.gui.UHud;
|
||||||
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
|
import com.minelittlepony.unicopia.entity.player.PlayerCamera;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ public class UnicopiaClient implements ClientModInitializer {
|
||||||
|
|
||||||
private void onTick(MinecraftClient client) {
|
private void onTick(MinecraftClient client) {
|
||||||
KeyBindingsHandler.INSTANCE.tick(client);
|
KeyBindingsHandler.INSTANCE.tick(client);
|
||||||
|
UHud.instance.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScreenInit(Screen screen, ButtonList buttons) {
|
private void onScreenInit(Screen screen, ButtonList buttons) {
|
||||||
|
|
|
@ -3,8 +3,11 @@ package com.minelittlepony.unicopia.client.gui;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
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.client.KeyBindingsHandler;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
@ -13,6 +16,7 @@ import net.minecraft.client.font.TextRenderer;
|
||||||
import net.minecraft.client.gui.DrawableHelper;
|
import net.minecraft.client.gui.DrawableHelper;
|
||||||
import net.minecraft.client.gui.hud.InGameHud;
|
import net.minecraft.client.gui.hud.InGameHud;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
|
|
||||||
|
@ -32,6 +36,10 @@ public class UHud extends DrawableHelper {
|
||||||
slots.add(new Slot(this, AbilitySlot.TERTIARY, AbilitySlot.TERTIARY, 36, 19, 3, 22, 17, 19).background(80, 105));
|
slots.add(new Slot(this, AbilitySlot.TERTIARY, AbilitySlot.TERTIARY, 36, 19, 3, 22, 17, 19).background(80, 105));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Text message;
|
||||||
|
private int messageTime;
|
||||||
|
|
||||||
public void render(InGameHud hud, MatrixStack matrices, float tickDelta) {
|
public void render(InGameHud hud, MatrixStack matrices, float tickDelta) {
|
||||||
|
|
||||||
if (client.player == null || client.player.isSpectator()) {
|
if (client.player == null || client.player.isSpectator()) {
|
||||||
|
@ -46,13 +54,17 @@ public class UHud extends DrawableHelper {
|
||||||
matrices.push();
|
matrices.push();
|
||||||
matrices.translate(104 + (scaledWidth - 50) / 2, 20 + scaledHeight - 70, 0);
|
matrices.translate(104 + (scaledWidth - 50) / 2, 20 + scaledHeight - 70, 0);
|
||||||
|
|
||||||
|
AbilityDispatcher abilities = Pony.of(client.player).getAbilities();
|
||||||
|
|
||||||
|
if (message != null && messageTime > 0) {
|
||||||
|
renderMessage(matrices, tickDelta);
|
||||||
|
}
|
||||||
|
|
||||||
RenderSystem.enableAlphaTest();
|
RenderSystem.enableAlphaTest();
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(HUD_TEXTURE);
|
client.getTextureManager().bindTexture(HUD_TEXTURE);
|
||||||
|
|
||||||
AbilityDispatcher abilities = Pony.of(client.player).getAbilities();
|
|
||||||
|
|
||||||
boolean swap = client.options.keySneak.isPressed();
|
boolean swap = client.options.keySneak.isPressed();
|
||||||
|
|
||||||
slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta));
|
slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta));
|
||||||
|
@ -64,8 +76,36 @@ public class UHud extends DrawableHelper {
|
||||||
matrices.pop();
|
matrices.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderMessage(MatrixStack matrices, float tickDelta) {
|
||||||
|
|
||||||
|
float time = messageTime - tickDelta;
|
||||||
|
int progress = Math.min(255, (int)(time * 255F / 20F));
|
||||||
|
|
||||||
|
if (progress > 8) {
|
||||||
|
|
||||||
|
int color = 0xFFFFFF;
|
||||||
|
|
||||||
|
int alpha = progress << 24 & -16777216;
|
||||||
|
|
||||||
|
color |= alpha;
|
||||||
|
|
||||||
|
drawCenteredText(matrices, client.textRenderer, message, 25, -15, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(Text message) {
|
||||||
|
this.message = message;
|
||||||
|
this.messageTime = 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
if (messageTime > 0) {
|
||||||
|
messageTime--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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().ifPresent(ability -> {
|
stat.getAbility(KeyBindingsHandler.INSTANCE.page).ifPresent(ability -> {
|
||||||
client.getTextureManager().bindTexture(ability.getIcon(Pony.of(client.player)));
|
client.getTextureManager().bindTexture(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);
|
||||||
client.getTextureManager().bindTexture(HUD_TEXTURE);
|
client.getTextureManager().bindTexture(HUD_TEXTURE);
|
||||||
|
|
Loading…
Reference in a new issue