Fixed mana cost estimate not accounting for the player's level, added a slight cooldown before mana regeneration

This commit is contained in:
Sollace 2020-10-11 09:56:10 +02:00
parent 1e4f97ed18
commit 6633d59a63
6 changed files with 118 additions and 57 deletions

View file

@ -44,9 +44,11 @@ public class UnicornCastingAbility implements Ability<Hit> {
public double getCostEstimate(Pony player) {
if (player.hasSpell()) {
String current = player.getSpell(true).getName();
String replaced = Streams.stream(player.getMaster().getItemsHand())
Spell replaced = Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry::getKeyFromStack)
.filter(i -> i != null && !current.equals(i))
.map(SpellRegistry.instance()::getSpellFromName)
.filter(i -> i != null)
.findFirst()
.orElse(null);
return replaced == null ? 2 : 4;

View file

@ -17,6 +17,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
class ManaRingSlot extends Slot {
private static final double TWO_PI = Math.PI * 2;
public ManaRingSlot(UHud uHud, AbilitySlot normalSlot, AbilitySlot backupSlot, int x, int y, int padding, int size,
int labelOffset, int iconSize) {
@ -28,14 +29,15 @@ class ManaRingSlot extends Slot {
matrices.push();
matrices.translate(24.5, 25.5, 0);
MagicReserves mana = Pony.of(uHud.client.player).getMagicalReserves();
Pony pony = Pony.of(uHud.client.player);
MagicReserves mana = pony.getMagicalReserves();
double arcBegin = 0;
arcBegin = renderRing(matrices, 17, 13, 0, mana.getMana(), 0xFF88FF99);
arcBegin = renderRing(matrices, 17, 13, 0, mana.getMana(), 0xFF88FF99, tickDelta);
if (!uHud.client.player.isCreative()) {
renderRing(matrices, 13, 11, 0, mana.getXp(), 0x88880099);
renderRing(matrices, 13, 11, 0, mana.getXp(), 0x88880099, tickDelta);
double cost = abilities.getStats().stream()
.mapToDouble(s -> s.getCost(KeyBindingsHandler.INSTANCE.page))
@ -46,27 +48,38 @@ class ManaRingSlot extends Slot {
float percent = mana.getMana().getPercentFill();
float max = mana.getMana().getMax();
cost = Math.min(max, cost * 10) / max;
cost *= 10;
cost /= 1 + pony.getLevel().get();
cost = Math.min(percent, cost);
int color = cost / max > percent ? 0xFF000099 : 0xFFFF0099;
cost = Math.min(percent, Math.min(max, cost) / max);
double angle = cost * Math.PI * 2;
renderArc(matrices, 13, 17, arcBegin - angle, angle, 0xFFFF0099, false);
renderArc(matrices, 13, 17, arcBegin - angle, angle, color, false);
}
}
arcBegin = renderRing(matrices, 17, 13, arcBegin, mana.getEnergy(), 0xFF002299);
arcBegin = renderRing(matrices, 17, 13, arcBegin, mana.getEnergy(), 0xFF002299, tickDelta);
matrices.pop();
super.renderContents(matrices, abilities, bSwap, tickDelta);
}
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color) {
double fill = bar.getPercentFill() * Math.PI * 2;
private double renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double offsetAngle, Bar bar, int color, float tickDelta) {
double fill = bar.getPercentFill() * TWO_PI;
double shadow = bar.getShadowFill() * TWO_PI;
renderArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true);
if (shadow > fill) {
color = (color & 0xFFFFFF00)
| ((color & 0x000000FF) / 2);
renderArc(matrices, innerRadius, outerRadius, offsetAngle + fill, shadow - fill, color, false);
}
return offsetAngle + fill;
}
@ -76,20 +89,20 @@ class ManaRingSlot extends Slot {
* @param mirrorHorizontally Whether or not the arc must be mirrored across the horizontal plane. Will produce a bar that grows from the middle filling both sides.
*/
static void renderArc(MatrixStack matrices, double innerRadius, double outerRadius, double startAngle, double arcAngle, int color, boolean mirrorHorizontally) {
float f = (color >> 24 & 255) / 255F;
float r = (color >> 24 & 255) / 255F;
float g = (color >> 16 & 255) / 255F;
float h = (color >> 8 & 255) / 255F;
float b = (color >> 8 & 255) / 255F;
float k = (color & 255) / 255F;
final double num_rings = 300;
final double twoPi = Math.PI * 2;
final double increment = twoPi / num_rings;
final double increment = TWO_PI / num_rings;
if (arcAngle < increment) {
return;
}
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, twoPi - increment);
final double maxAngle = MathHelper.clamp(startAngle + arcAngle, 0, TWO_PI - increment);
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.enableBlend();
@ -108,22 +121,22 @@ class ManaRingSlot extends Slot {
// center
bufferBuilder.vertex(model,
(float)(innerRadius * Math.sin(angle)),
(float)(innerRadius * Math.cos(angle)), 0).color(f, g, h, k).next();
(float)(innerRadius * Math.cos(angle)), 0).color(r, g, b, k).next();
// point one
bufferBuilder.vertex(model,
(float)(outerRadius * Math.sin(angle)),
(float)(outerRadius * Math.cos(angle)), 0).color(f, g, h, k).next();
(float)(outerRadius * Math.cos(angle)), 0).color(r, g, b, k).next();
// point two
bufferBuilder.vertex(model,
(float)(outerRadius * Math.sin(angle + increment)),
(float)(outerRadius * Math.cos(angle + increment)), 0).color(f, g, h, k).next();
(float)(outerRadius * Math.cos(angle + increment)), 0).color(r, g, b, k).next();
// back to center
bufferBuilder.vertex(model,
(float)(innerRadius * Math.sin(angle + increment)),
(float)(innerRadius * Math.cos(angle + increment)), 0).color(f, g, h, k).next();
(float)(innerRadius * Math.cos(angle + increment)), 0).color(r, g, b, k).next();
}

View file

@ -45,6 +45,11 @@ public interface MagicReserves {
return get() / getMax();
}
/**
* Gets the shadow fill used for animating on the UI
*/
float getShadowFill();
/**
* Adds a percentage increment to this bar's current value
*/

View file

@ -1,15 +1,16 @@
package com.minelittlepony.unicopia.entity.player;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.MathHelper;
public class ManaContainer implements MagicReserves {
public class ManaContainer implements MagicReserves, Tickable {
private final Pony pony;
private final Bar energy;
private final Bar exertion;
private final Bar mana;
private final Bar xp;
private final BarInst energy;
private final BarInst exertion;
private final BarInst mana;
private final BarInst xp;
public ManaContainer(Pony pony) {
this.pony = pony;
@ -39,6 +40,28 @@ public class ManaContainer implements MagicReserves {
return xp;
}
@Override
public void tick() {
exertion.tick();
energy.tick();
mana.tick();
xp.tick();
exertion.add(-10);
if (energy.get() > 5) {
energy.multiply(0.8F);
} else {
energy.add(-1);
}
if (!pony.getSpecies().canFly() || !pony.getPhysics().isFlying()) {
if (mana.getShadowFill() <= mana.getPercentFill()) {
mana.add(18);
}
}
}
class XpCollectingBar extends BarInst {
XpCollectingBar(TrackedData<Float> marker, float max, float initial) {
@ -69,6 +92,8 @@ public class ManaContainer implements MagicReserves {
private final TrackedData<Float> marker;
private final float max;
private float trailingValue;
BarInst(TrackedData<Float> marker, float max, float initial) {
this.marker = marker;
this.max = max;
@ -80,6 +105,11 @@ public class ManaContainer implements MagicReserves {
return pony.getMaster().getDataTracker().get(marker);
}
@Override
public float getShadowFill() {
return trailingValue;
}
@Override
public void set(float value) {
pony.getMaster().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax()));
@ -89,5 +119,20 @@ public class ManaContainer implements MagicReserves {
public float getMax() {
return max;
}
void tick() {
float fill = getPercentFill();
float tralingIncrement = 0.003F;
if (trailingValue > (fill - tralingIncrement) && trailingValue < (fill + tralingIncrement)) {
trailingValue = fill;
}
if (trailingValue < fill) {
trailingValue += tralingIncrement;
}
if (trailingValue > fill) {
trailingValue -= tralingIncrement;
}
}
}
}

View file

@ -11,9 +11,10 @@ import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Tickable;
import net.minecraft.util.registry.Registry;
public class PlayerAttributes {
public class PlayerAttributes implements Tickable {
public static final EntityAttribute EXTENDED_REACH_DISTANCE = register("unicopia.pegasus.reach", new ClampedEntityAttribute("player.reachDistance", 0, 0, 10).setTracked(true));
public static final EntityAttribute ENTITY_GRAVTY_MODIFIER = register("unicopia.player.gravity", (new EntityAttribute("player.gravityModifier", 1) {}).setTracked(true));
@ -28,7 +29,14 @@ public class PlayerAttributes {
public static final EntityAttributeModifier BAT_HANGING =
new EntityAttributeModifier(UUID.fromString("a54f2595-521e-480b-b9d5-6e750577a564"), "Bat Pony Hanging", -2, Operation.MULTIPLY_TOTAL);
public void applyAttributes(Pony pony) {
private final Pony pony;
public PlayerAttributes(Pony pony) {
this.pony = pony;
}
@Override
public void tick() {
PlayerEntity entity = pony.getMaster();
Race race = pony.getSpecies();

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.entity.player;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;
@ -31,6 +32,7 @@ import com.minelittlepony.unicopia.network.Transmittable;
import com.minelittlepony.unicopia.util.Copieable;
import com.minelittlepony.unicopia.util.MagicalDamageSource;
import com.minelittlepony.common.util.animation.LinearInterpolator;
import com.google.common.collect.Lists;
import com.minelittlepony.common.util.animation.Interpolator;
import com.mojang.authlib.GameProfile;
@ -50,9 +52,9 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmittable, Copieable<Pony> {
@ -68,11 +70,13 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
private final AbilityDispatcher powers = new AbilityDispatcher(this);
private final PlayerPhysics gravity = new PlayerPhysics(this);
private final PlayerAttributes attributes = new PlayerAttributes();
private final PlayerAttributes attributes = new PlayerAttributes(this);
private final PlayerCamera camera = new PlayerCamera(this);
private final MagicReserves mana;
private final ManaContainer mana;
private final PlayerLevelStore levels;
private final List<Tickable> tickers;
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
private final Interpolator interpolator = new LinearInterpolator();
@ -96,6 +100,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
this.entity = player;
this.mana = new ManaContainer(this);
this.levels = new PlayerLevelStore(this);
this.tickers = Lists.newArrayList(gravity, mana, attributes);
player.getDataTracker().startTracking(RACE, Race.HUMAN.ordinal());
player.getDataTracker().startTracking(EFFECT, new CompoundTag());
@ -282,8 +287,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
ticksHanging = 0;
}
gravity.tick();
if (hasSpell()) {
Attached effect = getSpell(Attached.class, true);
@ -298,18 +301,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
}
}
mana.getExertion().add(-10);
if (mana.getEnergy().get() > 5) {
mana.getEnergy().multiply(0.8F);
} else {
mana.getEnergy().add(-1);
}
if (!getSpecies().canFly() || !gravity.isFlying()) {
mana.getMana().add(15);
}
attributes.applyAttributes(this);
tickers.forEach(Tickable::tick);
if (dirty) {
sendCapabilities(true);
@ -339,30 +331,26 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
}
}
distance *= g;
distance = Math.max(0, distance - 5);
float d = distance;
getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> {
spell.getDisguise().onImpact(this, d, damageMultiplier);
});
distance = Math.max(0, (distance * g) - 5);
handleFall(distance, damageMultiplier);
return Optional.of(distance);
}
float d = distance;
getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> {
spell.getDisguise().onImpact(this, d, damageMultiplier);
});
handleFall(distance, damageMultiplier);
return Optional.empty();
}
private void handleFall(float distance, float damageMultiplier) {
getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> {
spell.getDisguise().onImpact(this, distance, damageMultiplier);
});
}
@Override
public void onJump() {
if (gravity.isGravityNegative()) {
Vec3d velocity = entity.getVelocity();
entity.setVelocity(velocity.x, velocity.y * -1, velocity.z);
entity.setVelocity(entity.getVelocity().multiply(1, -1, 1));
}
}