An ability will now show how much mana it will cost before activating

This commit is contained in:
Sollace 2020-10-09 19:05:12 +02:00
parent d337087447
commit e894fd3a58
15 changed files with 112 additions and 8 deletions

View file

@ -10,6 +10,12 @@ import net.minecraft.util.Identifier;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface Ability<T extends Hit> { public interface Ability<T extends Hit> {
/**
* The amount of energy this ability is expected to cost if the player were to cast it.
*/
double getCostEstimate(Pony player);
/** /**
* Returns the number of ticks the player must hold the ability key to trigger this ability. * Returns the number of ticks the player must hold the ability key to trigger this ability.
*/ */

View file

@ -1,10 +1,10 @@
package com.minelittlepony.unicopia.ability; package com.minelittlepony.unicopia.ability;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap; 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 javax.annotation.Nullable;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
@ -47,6 +47,10 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
} }
} }
public Collection<Stat> getStats() {
return stats.values();
}
public Stat getStat(AbilitySlot slot) { public Stat getStat(AbilitySlot slot) {
return stats.computeIfAbsent(slot, Stat::new); return stats.computeIfAbsent(slot, Stat::new);
} }
@ -141,6 +145,13 @@ public class AbilityDispatcher implements Tickable, NbtSerialisable {
return maxWarmup <= 0 ? 0 : ((float)warmup / (float)maxWarmup); return maxWarmup <= 0 ? 0 : ((float)warmup / (float)maxWarmup);
} }
public double getCost(long page) {
if (warmup <= 0) {
return 0;
}
return getAbility(page).map(ability -> ability.getCostEstimate(player)).orElse(0D);
}
public void setWarmup(int value) { public void setWarmup(int value) {
maxWarmup = value; maxWarmup = value;
warmup = value; warmup = value;

View file

@ -35,6 +35,11 @@ public class BatEeeeAbility implements Ability<Hit> {
return 1; return 1;
} }
@Override
public double getCostEstimate(Pony player) {
return 0;
}
@Override @Override
public boolean canUse(Race race) { public boolean canUse(Race race) {
return race == Race.BAT; return race == Race.BAT;

View file

@ -27,6 +27,11 @@ public class BatPonyHangAbility implements Ability<Multi> {
return 0; return 0;
} }
@Override
public double getCostEstimate(Pony player) {
return 0;
}
@Override @Override
public boolean canUse(Race race) { public boolean canUse(Race race) {
return race == Race.BAT; return race == Race.BAT;

View file

@ -25,6 +25,11 @@ public class CarryAbility implements Ability<Hit> {
return 10; return 10;
} }
@Override
public double getCostEstimate(Pony player) {
return 0;
}
@Override @Override
public boolean canUse(Race race) { public boolean canUse(Race race) {
return race.canFly(); return race.canFly();

View file

@ -88,6 +88,11 @@ public class ChangelingFeedAbility implements Ability<Hit> {
return list.stream().map(i -> (LivingEntity)i).collect(Collectors.toList()); return list.stream().map(i -> (LivingEntity)i).collect(Collectors.toList());
} }
@Override
public double getCostEstimate(Pony player) {
return 0;
}
@Override @Override
public void apply(Pony iplayer, Hit data) { public void apply(Pony iplayer, Hit data) {
PlayerEntity player = iplayer.getMaster(); PlayerEntity player = iplayer.getMaster();

View file

@ -44,6 +44,11 @@ public class EarthPonyGrowAbility implements Ability<Pos> {
return Pos.SERIALIZER; return Pos.SERIALIZER;
} }
@Override
public double getCostEstimate(Pony player) {
return 10;
}
@Override @Override
public void apply(Pony player, Pos data) { public void apply(Pony player, Pos data) {
int count = 0; int count = 0;

View file

@ -66,6 +66,11 @@ public class EarthPonyStompAbility implements Ability<Multi> {
return race.canUseEarth(); return race.canUseEarth();
} }
@Override
public double getCostEstimate(Pony player) {
return rad;
}
@Nullable @Nullable
@Override @Override
public Multi tryActivate(Pony player) { public Multi tryActivate(Pony player) {
@ -91,7 +96,6 @@ public class EarthPonyStompAbility implements Ability<Multi> {
return null; return null;
} }
@Override @Override
public Hit.Serializer<Multi> getSerializer() { public Hit.Serializer<Multi> getSerializer() {
return Multi.SERIALIZER; return Multi.SERIALIZER;

View file

@ -40,6 +40,21 @@ public class UnicornCastingAbility implements Ability<Hit> {
return Hit.SERIALIZER; return Hit.SERIALIZER;
} }
@Override
public double getCostEstimate(Pony player) {
if (player.hasSpell()) {
String current = player.getSpell(true).getName();
String replaced = Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry::getKeyFromStack)
.filter(i -> i != null && !current.equals(i))
.findFirst()
.orElse(null);
return replaced == null ? 2 : 4;
}
return 4;
}
@Override @Override
public void apply(Pony player, Hit data) { public void apply(Pony player, Hit data) {

View file

@ -53,9 +53,14 @@ public class UnicornProjectileAbility implements Ability<Hit> {
return Hit.SERIALIZER; return Hit.SERIALIZER;
} }
@Override
public double getCostEstimate(Pony player) {
return 7;
}
@Override @Override
public void apply(Pony player, Hit data) { public void apply(Pony player, Hit data) {
player.subtractEnergyCost(7); player.subtractEnergyCost(getCostEstimate(player));
getThrown(player).orElseGet(AttractiveSpell::new).toss(player); getThrown(player).orElseGet(AttractiveSpell::new).toss(player);
} }

View file

@ -54,6 +54,16 @@ public class UnicornTeleportAbility implements Ability<Pos> {
return race.canCast(); return race.canCast();
} }
@Override
public double getCostEstimate(Pony player) {
Pos pos = tryActivate(player);
if (pos == null) {
return 0;
}
return pos.distanceTo(player) / 10;
}
@Override @Override
public Pos tryActivate(Pony player) { public Pos tryActivate(Pony player) {
int maxDistance = player.getMaster().isCreative() ? 1000 : 100; int maxDistance = player.getMaster().isCreative() ? 1000 : 100;
@ -118,7 +128,7 @@ public class UnicornTeleportAbility implements Ability<Pos> {
iplayer.getWorld().playSound(null, iplayer.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1); iplayer.getWorld().playSound(null, iplayer.getOrigin(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, 1, 1);
PlayerEntity player = iplayer.getMaster(); PlayerEntity player = iplayer.getMaster();
double distance = Math.sqrt(player.squaredDistanceTo(data.x, data.y, data.z)) / 10; double distance = data.distanceTo(iplayer) / 10;
if (player.hasVehicle()) { if (player.hasVehicle()) {
Entity mount = player.getVehicle(); Entity mount = player.getVehicle();

View file

@ -1,5 +1,7 @@
package com.minelittlepony.unicopia.ability.data; package com.minelittlepony.unicopia.ability.data;
import com.minelittlepony.unicopia.ability.magic.Caster;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -39,4 +41,8 @@ public class Pos extends Hit {
public BlockPos pos() { public BlockPos pos() {
return new BlockPos(x, y, z); return new BlockPos(x, y, z);
} }
public double distanceTo(Caster<?> caster) {
return Math.sqrt(caster.getEntity().squaredDistanceTo(x, y, z));
}
} }

View file

@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.client.gui;
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.MagicReserves; import com.minelittlepony.unicopia.entity.player.MagicReserves;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar; import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
@ -32,6 +33,27 @@ class ManaRingSlot extends Slot {
double arcBegin = 0; double arcBegin = 0;
arcBegin = renderRing(matrices, 17, 13, 0, mana.getMana(), 0xFF88FF99); arcBegin = renderRing(matrices, 17, 13, 0, mana.getMana(), 0xFF88FF99);
if (!uHud.client.player.isCreative()) {
double cost = abilities.getStats().stream()
.mapToDouble(s -> s.getCost(KeyBindingsHandler.INSTANCE.page))
.reduce(Double::sum)
.getAsDouble();
if (cost > 0) {
float percent = mana.getMana().getPercentFill();
float max = mana.getMana().getMax();
cost = Math.min(max, cost) / max;
cost = Math.min(percent, cost);
double angle = cost * Math.PI * 2;
renderArc(matrices, 13, 17, arcBegin - angle, angle, 0xFFFF0099, false);
}
}
arcBegin = renderRing(matrices, 17, 13, arcBegin, mana.getEnergy(), 0xFF002299); arcBegin = renderRing(matrices, 17, 13, arcBegin, mana.getEnergy(), 0xFF002299);
matrices.pop(); matrices.pop();
@ -42,7 +64,7 @@ class ManaRingSlot extends Slot {
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color) { private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color) {
double fill = bar.getPercentFill() * Math.PI * 2; double fill = bar.getPercentFill() * Math.PI * 2;
renderArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, false); renderArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true);
return offsetAngle + fill; return offsetAngle + fill;
} }

View file

@ -67,7 +67,7 @@ class Slot {
uHud.renderAbilityIcon(matrices, abilities.getStat(bSwap ? bSlot : aSlot), slotPadding / 2, slotPadding / 2, iconSize, iconSize, iconSize, iconSize); uHud.renderAbilityIcon(matrices, abilities.getStat(bSwap ? bSlot : aSlot), slotPadding / 2, slotPadding / 2, iconSize, iconSize, iconSize, iconSize);
if (cooldown > 0 && cooldown < 1) { if (cooldown > 0 && cooldown <= 1) {
float lerpCooldown = MathHelper.lerp(tickDelta, cooldown, lastCooldown); float lerpCooldown = MathHelper.lerp(tickDelta, cooldown, lastCooldown);
lastCooldown = lerpCooldown; lastCooldown = lerpCooldown;

View file

@ -305,7 +305,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
} }
if (!getSpecies().canFly() || !gravity.isFlying()) { if (!getSpecies().canFly() || !gravity.isFlying()) {
mana.getMana().add(60); mana.getMana().add(15);
} }
attributes.applyAttributes(this); attributes.applyAttributes(this);
@ -368,7 +368,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
@Override @Override
public boolean subtractEnergyCost(double foodSubtract) { public boolean subtractEnergyCost(double foodSubtract) {
if (!entity.abilities.creativeMode) { if (!entity.isCreative()) {
float currentMana = mana.getMana().get(); float currentMana = mana.getMana().get();
float foodManaRatio = 10; float foodManaRatio = 10;