mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Rewrite controls
This commit is contained in:
parent
019c9e17ed
commit
ee7c67afe4
8 changed files with 234 additions and 111 deletions
|
@ -1,41 +1,40 @@
|
|||
package com.minelittlepony.unicopia.ability;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
||||
public interface Abilities {
|
||||
Map<Identifier, Integer> KEYS_CODES = new HashMap<>();
|
||||
Map<AbilitySlot, Set<Ability<?>>> BY_SLOT = new EnumMap<>(AbilitySlot.class);
|
||||
MutableRegistry<Ability<?>> REGISTRY = new SimpleRegistry<>();
|
||||
|
||||
// unicorn / alicorn
|
||||
Ability<?> TELEPORT = register(new UnicornTeleportAbility(), "teleport", GLFW.GLFW_KEY_O);
|
||||
Ability<?> CAST = register(new UnicornCastingAbility(), "cast", GLFW.GLFW_KEY_P);
|
||||
Ability<?> TELEPORT = register(new UnicornTeleportAbility(), "teleport", AbilitySlot.PRIMARY);
|
||||
Ability<?> CAST = register(new UnicornCastingAbility(), "cast", AbilitySlot.SECONDARY);
|
||||
|
||||
// earth / alicorn
|
||||
Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", GLFW.GLFW_KEY_N);
|
||||
Ability<?> STOMP = register(new EarthPonyStompAbility(), "stomp", GLFW.GLFW_KEY_M);
|
||||
Ability<?> STOMP = register(new EarthPonyStompAbility(), "stomp", AbilitySlot.PRIMARY);
|
||||
Ability<?> GROW = register(new EarthPonyGrowAbility(), "grow", AbilitySlot.SECONDARY);
|
||||
|
||||
// pegasus / bat / alicorn / changeling
|
||||
Ability<?> CARRY = register(new CarryAbility(), "carry", GLFW.GLFW_KEY_K);
|
||||
Ability<?> CARRY = register(new CarryAbility(), "carry", AbilitySlot.PASSIVE);
|
||||
|
||||
// pegasus / alicorn
|
||||
Ability<?> CLOUD = register(new PegasusCloudInteractionAbility(), "cloud", GLFW.GLFW_KEY_J);
|
||||
Ability<?> CLOUD = register(new PegasusCloudInteractionAbility(), "cloud", AbilitySlot.TERTIARY);
|
||||
|
||||
// changeling
|
||||
Ability<?> FEED = register(new ChangelingFeedAbility(), "feed", GLFW.GLFW_KEY_O);
|
||||
Ability<?> TRAP = register(new ChangelingTrapAbility(), "trap", GLFW.GLFW_KEY_L);
|
||||
Ability<?> DISGUISE = register(new ChangelingDisguiseAbility(), "disguise", AbilitySlot.PRIMARY);
|
||||
Ability<?> FEED = register(new ChangelingFeedAbility(), "feed", AbilitySlot.SECONDARY);
|
||||
Ability<?> TRAP = register(new ChangelingTrapAbility(), "trap", AbilitySlot.TERTIARY);
|
||||
|
||||
Ability<?> DISGUISE = register(new ChangelingDisguiseAbility(), "disguise", GLFW.GLFW_KEY_P);
|
||||
|
||||
static <T extends Ability<?>> T register(T power, String name, int keyCode) {
|
||||
static <T extends Ability<?>> T register(T power, String name, AbilitySlot slot) {
|
||||
Identifier id = new Identifier("unicopia", name);
|
||||
KEYS_CODES.put(id, keyCode);
|
||||
BY_SLOT.computeIfAbsent(slot, s -> new HashSet<>()).add(power);
|
||||
return REGISTRY.add(id, power);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package com.minelittlepony.unicopia.ability;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.entity.Updatable;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
@ -18,15 +21,7 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable {
|
|||
|
||||
private final Pony player;
|
||||
|
||||
/**
|
||||
* Ticks of warmup before an ability is triggered.
|
||||
*/
|
||||
private int warmup;
|
||||
|
||||
/**
|
||||
* Ticks of cooldown after an ability has been triggered.
|
||||
*/
|
||||
private int cooldown;
|
||||
private final Map<AbilitySlot, Stat> stats = new EnumMap<>(AbilitySlot.class);
|
||||
|
||||
/**
|
||||
* True once the current ability has been triggered.
|
||||
|
@ -35,69 +30,90 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable {
|
|||
|
||||
private Optional<Ability<?>> activeAbility = Optional.empty();
|
||||
|
||||
private AbilitySlot activeSlot = AbilitySlot.NONE;
|
||||
|
||||
public AbilityDispatcher(Pony player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the currrent ability can we swapped out.
|
||||
* Returns true if the current ability can we swapped out.
|
||||
*/
|
||||
boolean canSwitchStates() {
|
||||
return !activeAbility.isPresent() || (warmup != 0) || (triggered && cooldown == 0);
|
||||
return !activeAbility.isPresent() || getStat(getActiveSlot()).canSwitchStates();
|
||||
}
|
||||
|
||||
public void tryUseAbility(Ability<?> power) {
|
||||
if (canSwitchStates()) {
|
||||
setAbility(power);
|
||||
public AbilitySlot getActiveSlot() {
|
||||
return activeSlot;
|
||||
}
|
||||
|
||||
public void cancelAbility(AbilitySlot slot) {
|
||||
if (getActiveSlot() == slot && canSwitchStates()) {
|
||||
setActiveAbility(slot, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void tryClearAbility() {
|
||||
public void activate(AbilitySlot slot) {
|
||||
if (canSwitchStates()) {
|
||||
setAbility(null);
|
||||
getAbility(slot).ifPresent(ability -> setActiveAbility(slot, ability));
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void setAbility(Ability<?> power) {
|
||||
public Stat getStat(AbilitySlot slot) {
|
||||
return stats.computeIfAbsent(slot, Stat::new);
|
||||
}
|
||||
|
||||
public Optional<Ability<?>> getAbility(AbilitySlot slot) {
|
||||
Race race = player.getSpecies();
|
||||
return Abilities.BY_SLOT.get(slot).stream().filter(a -> a.canUse(race)).findFirst();
|
||||
}
|
||||
|
||||
protected synchronized void setActiveAbility(AbilitySlot slot, Ability<?> power) {
|
||||
if (activeAbility.orElse(null) != power) {
|
||||
activeSlot = slot;
|
||||
triggered = false;
|
||||
activeAbility = Optional.ofNullable(power);
|
||||
warmup = activeAbility.map(p -> p.getWarmupTime(player)).orElse(0);
|
||||
cooldown = 0;
|
||||
Stat stat = getStat(slot);
|
||||
stat.setWarmup(activeAbility.map(p -> p.getWarmupTime(player)).orElse(0));
|
||||
stat.setCooldown(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected synchronized Optional<Ability<?>> getUsableAbility() {
|
||||
protected synchronized Optional<Ability<?>> getActiveAbility() {
|
||||
Stat stat = getStat(getActiveSlot());
|
||||
return activeAbility.filter(ability -> {
|
||||
return (!(ability == null || (triggered && warmup == 0 && cooldown == 0)) && ability.canUse(player.getSpecies()));
|
||||
return (!(ability == null || (triggered && stat.warmup == 0 && stat.cooldown == 0)) && ability.canUse(player.getSpecies()));
|
||||
});
|
||||
}
|
||||
|
||||
public int getRemainingCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
getUsableAbility().ifPresent(this::activate);
|
||||
getActiveAbility().ifPresent(this::activate);
|
||||
}
|
||||
|
||||
private <T extends Hit> void activate(Ability<T> ability) {
|
||||
if (warmup > 0) {
|
||||
warmup--;
|
||||
Stat stat = getStat(getActiveSlot());
|
||||
|
||||
stats.values().forEach(s -> {
|
||||
if (s != stat) {
|
||||
s.idle();
|
||||
}
|
||||
});
|
||||
|
||||
if (stat.warmup > 0) {
|
||||
stat.warmup--;
|
||||
System.out.println("warming up");
|
||||
ability.preApply(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cooldown > 0) {
|
||||
cooldown--;
|
||||
if (stat.tickInactive()) {
|
||||
System.out.println("cooling down");
|
||||
ability.postApply(player);
|
||||
|
||||
if (cooldown <= 0) {
|
||||
setAbility(null);
|
||||
if (stat.cooldown <= 0) {
|
||||
setActiveAbility(AbilitySlot.NONE, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -108,7 +124,7 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable {
|
|||
|
||||
if (ability.canActivate(player.getWorld(), player)) {
|
||||
triggered = true;
|
||||
cooldown = ability.getCooldownTime(player);
|
||||
stat.setCooldown(ability.getCooldownTime(player));
|
||||
|
||||
if (player.isClientPlayer()) {
|
||||
T data = ability.tryActivate(player);
|
||||
|
@ -116,22 +132,28 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable {
|
|||
if (data != null) {
|
||||
Channel.PLAYER_ABILITY.send(new MsgPlayerAbility<>(ability, data));
|
||||
} else {
|
||||
cooldown = 0;
|
||||
stat.setCooldown(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown <= 0) {
|
||||
setAbility(null);
|
||||
if (stat.cooldown <= 0) {
|
||||
setActiveAbility(AbilitySlot.NONE, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
compound.putBoolean("triggered", triggered);
|
||||
compound.putInt("warmup", warmup);
|
||||
compound.putInt("cooldown", cooldown);
|
||||
getUsableAbility().ifPresent(ability -> {
|
||||
if (compound.contains("stats")) {
|
||||
stats.clear();
|
||||
CompoundTag li = compound.getCompound("stats");
|
||||
li.getKeys().forEach(key -> {
|
||||
getStat(AbilitySlot.valueOf(key)).fromNBT(li.getCompound(key));
|
||||
});
|
||||
}
|
||||
compound.putInt("activeSlot", activeSlot.ordinal());
|
||||
getActiveAbility().ifPresent(ability -> {
|
||||
compound.putString("activeAbility", Abilities.REGISTRY.getId(ability).toString());
|
||||
});
|
||||
}
|
||||
|
@ -139,8 +161,97 @@ public class AbilityDispatcher implements Updatable, NbtSerialisable {
|
|||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
triggered = compound.getBoolean("triggered");
|
||||
warmup = compound.getInt("warmup");
|
||||
cooldown = compound.getInt("cooldown");
|
||||
CompoundTag li = new CompoundTag();
|
||||
stats.forEach((key, value) -> li.put(key.name(), value.toNBT()));
|
||||
compound.put("stats", li);
|
||||
activeSlot = compound.contains("activeSlot") ? AbilitySlot.values()[compound.getInt("activeSlot")] : activeSlot;
|
||||
activeAbility = Abilities.REGISTRY.getOrEmpty(new Identifier(compound.getString("activeAbility")));
|
||||
}
|
||||
|
||||
public class Stat implements NbtSerialisable {
|
||||
|
||||
/**
|
||||
* Ticks of warmup before an ability is triggered.
|
||||
*/
|
||||
private int warmup;
|
||||
private int maxWarmup;
|
||||
|
||||
/**
|
||||
* Ticks of cooldown after an ability has been triggered.
|
||||
*/
|
||||
private int cooldown;
|
||||
private int maxCooldown;
|
||||
|
||||
public final AbilitySlot slot;
|
||||
|
||||
private Stat(AbilitySlot slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current ability can we swapped out.
|
||||
*/
|
||||
boolean canSwitchStates() {
|
||||
return (warmup != 0) || (triggered && cooldown == 0);
|
||||
}
|
||||
|
||||
public int getRemainingCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
public float getFillProgress() {
|
||||
float cooldown = getWarmup();
|
||||
if (cooldown <= 0 || cooldown >= 1) {
|
||||
return getCooldown();
|
||||
}
|
||||
return 1 - cooldown;
|
||||
}
|
||||
|
||||
public float getCooldown() {
|
||||
return maxCooldown <= 0 ? 0 : ((float)cooldown / (float)maxCooldown);
|
||||
}
|
||||
|
||||
public void setCooldown(int value) {
|
||||
cooldown = value;
|
||||
maxCooldown = value;
|
||||
}
|
||||
|
||||
public float getWarmup() {
|
||||
return maxWarmup <= 0 ? 0 : ((float)warmup / (float)maxWarmup);
|
||||
}
|
||||
|
||||
public void setWarmup(int value) {
|
||||
maxWarmup = value;
|
||||
warmup = value;
|
||||
}
|
||||
|
||||
public void idle() {
|
||||
if (warmup > 0) {
|
||||
warmup--;
|
||||
}
|
||||
if (cooldown > 0) {
|
||||
cooldown--;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean tickInactive() {
|
||||
return cooldown > 0 && cooldown-- > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
compound.putInt("warmup", warmup);
|
||||
compound.putInt("cooldown", cooldown);
|
||||
compound.putInt("maxWarmup", maxWarmup);
|
||||
compound.putInt("maxCooldown", maxCooldown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
warmup = compound.getInt("warmup");
|
||||
cooldown = compound.getInt("cooldown");
|
||||
maxWarmup = compound.getInt("maxWarmup");
|
||||
maxCooldown = compound.getInt("maxCooldown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.minelittlepony.unicopia.ability;
|
||||
|
||||
public enum AbilitySlot {
|
||||
NONE,
|
||||
PRIMARY,
|
||||
SECONDARY,
|
||||
TERTIARY,
|
||||
PASSIVE;
|
||||
|
||||
public boolean isPassive() {
|
||||
return this == PASSIVE;
|
||||
}
|
||||
}
|
|
@ -193,7 +193,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
|
|||
|
||||
@Override
|
||||
public void postApply(Pony player) {
|
||||
int timeDiff = getCooldownTime(player) - player.getAbilities().getRemainingCooldown();
|
||||
int timeDiff = getCooldownTime(player) - player.getAbilities().getStat(player.getAbilities().getActiveSlot()).getRemainingCooldown();
|
||||
|
||||
if (player.getOwner().getEntityWorld().getTime() % 1 == 0 || timeDiff == 0) {
|
||||
spawnParticleRing(player.getOwner(), timeDiff, 1);
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package com.minelittlepony.unicopia.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.ability.Ability;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding;
|
||||
|
@ -24,27 +20,25 @@ import net.minecraft.util.Identifier;
|
|||
class KeyBindingsHandler {
|
||||
private final String KEY_CATEGORY = "unicopia.category.name";
|
||||
|
||||
private final Map<InputUtil.KeyCode, List<Ability<? extends Hit>>> keyPools = new HashMap<>();
|
||||
|
||||
private final Set<KeyBinding> bindings = new HashSet<>();
|
||||
private final Map<KeyBinding, AbilitySlot> keys = new HashMap<>();
|
||||
|
||||
private final Set<KeyBinding> pressed = new HashSet<>();
|
||||
|
||||
private Collection<Ability<?>> getKeyCodePool(KeyBinding keyCode) {
|
||||
return keyPools.computeIfAbsent(keyCode.getDefaultKeyCode(), i -> new ArrayList<>());
|
||||
}
|
||||
|
||||
public void addKeybind(Ability<?> p) {
|
||||
public KeyBindingsHandler() {
|
||||
KeyBindingRegistry.INSTANCE.addCategory(KEY_CATEGORY);
|
||||
|
||||
Identifier id = Abilities.REGISTRY.getId(p);
|
||||
int code = Abilities.KEYS_CODES.get(id);
|
||||
addKeybind(GLFW.GLFW_KEY_O, AbilitySlot.PRIMARY);
|
||||
addKeybind(GLFW.GLFW_KEY_P, AbilitySlot.SECONDARY);
|
||||
addKeybind(GLFW.GLFW_KEY_L, AbilitySlot.TERTIARY);
|
||||
}
|
||||
|
||||
FabricKeyBinding b = FabricKeyBinding.Builder.create(id, InputUtil.Type.KEYSYM, code, KEY_CATEGORY).build();
|
||||
public void addKeybind(int code, AbilitySlot slot) {
|
||||
KeyBindingRegistry.INSTANCE.addCategory(KEY_CATEGORY);
|
||||
|
||||
FabricKeyBinding b = FabricKeyBinding.Builder.create(new Identifier("unicopia", slot.name().toLowerCase()), InputUtil.Type.KEYSYM, code, KEY_CATEGORY).build();
|
||||
KeyBindingRegistry.INSTANCE.register(b);
|
||||
|
||||
getKeyCodePool(b).add(p);
|
||||
bindings.add(b);
|
||||
keys.put(b, slot);
|
||||
}
|
||||
|
||||
public void tick(MinecraftClient client) {
|
||||
|
@ -54,19 +48,20 @@ class KeyBindingsHandler {
|
|||
}
|
||||
Pony iplayer = Pony.of(client.player);
|
||||
|
||||
for (KeyBinding i : bindings) {
|
||||
for (KeyBinding i : keys.keySet()) {
|
||||
AbilitySlot slot = keys.get(i);
|
||||
if (slot == AbilitySlot.PRIMARY && client.options.keySneak.isPressed()) {
|
||||
slot = AbilitySlot.PASSIVE;
|
||||
}
|
||||
|
||||
if (i.isPressed()) {
|
||||
if (pressed.add(i)) {
|
||||
System.out.println("key press " + i);
|
||||
Race race = iplayer.getSpecies();
|
||||
getKeyCodePool(i).stream()
|
||||
.filter(power -> power.canUse(race))
|
||||
.findFirst()
|
||||
.ifPresent(iplayer.getAbilities()::tryUseAbility);
|
||||
System.out.println("Key down " + slot);
|
||||
iplayer.getAbilities().activate(slot);
|
||||
}
|
||||
} else if (pressed.remove(i)) {
|
||||
System.out.println("key release " + i);
|
||||
iplayer.getAbilities().tryClearAbility();
|
||||
System.out.println("Key up " + slot);
|
||||
iplayer.getAbilities().cancelAbility(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,8 @@ import static com.minelittlepony.unicopia.EquinePredicates.PLAYER_UNICORN;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.common.event.ClientReadyCallback;
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.container.SpellbookResultSlot;
|
||||
import com.minelittlepony.unicopia.ducks.Colourful;
|
||||
|
@ -45,8 +43,6 @@ public class UnicopiaClient implements ClientModInitializer {
|
|||
URenderers.bootstrap();
|
||||
|
||||
ClientTickCallback.EVENT.register(this::tick);
|
||||
ClientReadyCallback.EVENT.register(client -> Abilities.REGISTRY.stream().forEach(keyboard::addKeybind));
|
||||
|
||||
DefaultTexturesRegistry.getDefaultTextures().add(new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, SpellbookResultSlot.EMPTY_GEM_SLOT));
|
||||
|
||||
ColorProviderRegistry.ITEM.register((stack, tint) -> {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.minelittlepony.unicopia.client.gui;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -14,8 +17,8 @@ public class UHud extends DrawableHelper {
|
|||
|
||||
public static final Identifier HUD_TEXTURE = new Identifier("unicopia", "textures/gui/hud.png");
|
||||
|
||||
private Slot secondarySlot = new Slot(26, 0);
|
||||
private Slot tertiarySlot = new Slot(36, 24);
|
||||
private Slot secondarySlot = new Slot(AbilitySlot.SECONDARY, 26, 0);
|
||||
private Slot tertiarySlot = new Slot(AbilitySlot.TERTIARY, 36, 24);
|
||||
|
||||
public void render(InGameHud hud, float tickDelta) {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
@ -34,55 +37,60 @@ public class UHud extends DrawableHelper {
|
|||
int frameHeight = 54;
|
||||
int frameWidth = 54;
|
||||
|
||||
AbilityDispatcher abilities = Pony.of(client.player).getAbilities();
|
||||
|
||||
blit(x, y, 0, 0, frameWidth, frameHeight, 128, 128); // background
|
||||
|
||||
float progressPercent = 0.25F;
|
||||
int progressHeight = (int)(frameHeight * progressPercent);
|
||||
float progressPercent = abilities.getStat(AbilitySlot.PRIMARY).getFillProgress();
|
||||
|
||||
blit(x, y + (frameHeight - progressHeight),
|
||||
61, frameHeight - progressHeight,
|
||||
frameWidth, progressHeight, 128, 128); // progress
|
||||
if (progressPercent > 0 && progressPercent < 1) {
|
||||
int progressHeight = (int)(frameHeight * progressPercent);
|
||||
|
||||
blit(x, y + (frameHeight - progressHeight),
|
||||
61, frameHeight - progressHeight,
|
||||
frameWidth, progressHeight, 128, 128); // progress
|
||||
}
|
||||
|
||||
blit(x, y, 0, 54, frameWidth, frameHeight, 128, 128); // frame
|
||||
|
||||
|
||||
|
||||
secondarySlot.render(x, y, 50, 100, tickDelta);
|
||||
tertiarySlot.render(x, y, 5, 10, tickDelta);
|
||||
secondarySlot.render(abilities, x, y, tickDelta);
|
||||
tertiarySlot.render(abilities, x, y, tickDelta);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.disableAlphaTest();
|
||||
}
|
||||
|
||||
|
||||
static class Slot {
|
||||
|
||||
private final AbilitySlot slot;
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
private float lastCooldown;
|
||||
|
||||
public Slot(int x, int y) {
|
||||
public Slot(AbilitySlot slot, int x, int y) {
|
||||
this.slot = slot;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
void render(int x, int y, float cooldown, float maxCooldown, float tickDelta) {
|
||||
void render(AbilityDispatcher abilities, int x, int y, float tickDelta) {
|
||||
x += this.x;
|
||||
y += this.y;
|
||||
|
||||
if (cooldown > 0 && maxCooldown > 0 && cooldown < maxCooldown) {
|
||||
float cooldown = abilities.getStat(slot).getFillProgress();
|
||||
|
||||
if (cooldown > 0 && cooldown < 1) {
|
||||
float lerpCooldown = MathHelper.lerp(tickDelta, cooldown, lastCooldown);
|
||||
|
||||
lastCooldown = lerpCooldown;
|
||||
|
||||
float cooldownPercent = 1 - lerpCooldown / maxCooldown;
|
||||
|
||||
int slotPadding = 4;
|
||||
int slotSize = 15;
|
||||
|
||||
int progressBottom = y + slotPadding + slotSize;
|
||||
int progressTop = progressBottom - (int)(15F * cooldownPercent);
|
||||
int progressTop = progressBottom - (int)(15F * cooldown);
|
||||
|
||||
fill(x + slotPadding, progressTop, x + slotPadding + slotSize, progressBottom, 0xAAFFFFFF);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.InteractionManager;
|
||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ducks.PonyContainer;
|
||||
import com.minelittlepony.unicopia.enchanting.PageOwner;
|
||||
import com.minelittlepony.unicopia.entity.FlightControl;
|
||||
import com.minelittlepony.unicopia.entity.Ponylike;
|
||||
import com.minelittlepony.unicopia.entity.RaceContainer;
|
||||
import com.minelittlepony.unicopia.magic.Caster;
|
||||
import com.minelittlepony.unicopia.network.Transmittable;
|
||||
|
@ -97,9 +97,10 @@ public interface Pony extends Caster<PlayerEntity>, RaceContainer<PlayerEntity>,
|
|||
return InteractionManager.instance().isClientPlayer(getOwner());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
static Pony of(@Nullable PlayerEntity player) {
|
||||
return Ponylike.<Pony>of(player);
|
||||
return player == null ? null : ((PonyContainer<Pony>)player).get();
|
||||
}
|
||||
|
||||
static boolean equal(GameProfile one, GameProfile two) {
|
||||
|
|
Loading…
Reference in a new issue