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) { public double getCostEstimate(Pony player) {
if (player.hasSpell()) { if (player.hasSpell()) {
String current = player.getSpell(true).getName(); String current = player.getSpell(true).getName();
String replaced = Streams.stream(player.getMaster().getItemsHand()) Spell replaced = Streams.stream(player.getMaster().getItemsHand())
.map(SpellRegistry::getKeyFromStack) .map(SpellRegistry::getKeyFromStack)
.filter(i -> i != null && !current.equals(i)) .filter(i -> i != null && !current.equals(i))
.map(SpellRegistry.instance()::getSpellFromName)
.filter(i -> i != null)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
return replaced == null ? 2 : 4; return replaced == null ? 2 : 4;

View file

@ -17,6 +17,7 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
class ManaRingSlot extends Slot { 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, public ManaRingSlot(UHud uHud, AbilitySlot normalSlot, AbilitySlot backupSlot, int x, int y, int padding, int size,
int labelOffset, int iconSize) { int labelOffset, int iconSize) {
@ -28,14 +29,15 @@ class ManaRingSlot extends Slot {
matrices.push(); matrices.push();
matrices.translate(24.5, 25.5, 0); 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; 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()) { 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() double cost = abilities.getStats().stream()
.mapToDouble(s -> s.getCost(KeyBindingsHandler.INSTANCE.page)) .mapToDouble(s -> s.getCost(KeyBindingsHandler.INSTANCE.page))
@ -46,27 +48,38 @@ class ManaRingSlot extends Slot {
float percent = mana.getMana().getPercentFill(); float percent = mana.getMana().getPercentFill();
float max = mana.getMana().getMax(); 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; 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(); matrices.pop();
super.renderContents(matrices, abilities, bSwap, tickDelta); super.renderContents(matrices, abilities, bSwap, tickDelta);
} }
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, float tickDelta) {
double fill = bar.getPercentFill() * Math.PI * 2; double fill = bar.getPercentFill() * TWO_PI;
double shadow = bar.getShadowFill() * TWO_PI;
renderArc(matrices, innerRadius, outerRadius, offsetAngle, fill, color, true); 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; 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. * @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) { 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 g = (color >> 16 & 255) / 255F;
float h = (color >> 8 & 255) / 255F; float b = (color >> 8 & 255) / 255F;
float k = (color & 255) / 255F; float k = (color & 255) / 255F;
final double num_rings = 300; 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) { if (arcAngle < increment) {
return; 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(); BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
@ -108,22 +121,22 @@ class ManaRingSlot extends Slot {
// center // center
bufferBuilder.vertex(model, bufferBuilder.vertex(model,
(float)(innerRadius * Math.sin(angle)), (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 // point one
bufferBuilder.vertex(model, bufferBuilder.vertex(model,
(float)(outerRadius * Math.sin(angle)), (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 // point two
bufferBuilder.vertex(model, bufferBuilder.vertex(model,
(float)(outerRadius * Math.sin(angle + increment)), (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 // back to center
bufferBuilder.vertex(model, bufferBuilder.vertex(model,
(float)(innerRadius * Math.sin(angle + increment)), (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(); 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 * Adds a percentage increment to this bar's current value
*/ */

View file

@ -1,15 +1,16 @@
package com.minelittlepony.unicopia.entity.player; package com.minelittlepony.unicopia.entity.player;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class ManaContainer implements MagicReserves { public class ManaContainer implements MagicReserves, Tickable {
private final Pony pony; private final Pony pony;
private final Bar energy; private final BarInst energy;
private final Bar exertion; private final BarInst exertion;
private final Bar mana; private final BarInst mana;
private final Bar xp; private final BarInst xp;
public ManaContainer(Pony pony) { public ManaContainer(Pony pony) {
this.pony = pony; this.pony = pony;
@ -39,6 +40,28 @@ public class ManaContainer implements MagicReserves {
return xp; 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 { class XpCollectingBar extends BarInst {
XpCollectingBar(TrackedData<Float> marker, float max, float initial) { XpCollectingBar(TrackedData<Float> marker, float max, float initial) {
@ -69,6 +92,8 @@ public class ManaContainer implements MagicReserves {
private final TrackedData<Float> marker; private final TrackedData<Float> marker;
private final float max; private final float max;
private float trailingValue;
BarInst(TrackedData<Float> marker, float max, float initial) { BarInst(TrackedData<Float> marker, float max, float initial) {
this.marker = marker; this.marker = marker;
this.max = max; this.max = max;
@ -80,6 +105,11 @@ public class ManaContainer implements MagicReserves {
return pony.getMaster().getDataTracker().get(marker); return pony.getMaster().getDataTracker().get(marker);
} }
@Override
public float getShadowFill() {
return trailingValue;
}
@Override @Override
public void set(float value) { public void set(float value) {
pony.getMaster().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax())); pony.getMaster().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax()));
@ -89,5 +119,20 @@ public class ManaContainer implements MagicReserves {
public float getMax() { public float getMax() {
return max; 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.EntityAttributeModifier.Operation;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Tickable;
import net.minecraft.util.registry.Registry; 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 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)); 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 = public static final EntityAttributeModifier BAT_HANGING =
new EntityAttributeModifier(UUID.fromString("a54f2595-521e-480b-b9d5-6e750577a564"), "Bat Pony Hanging", -2, Operation.MULTIPLY_TOTAL); 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(); PlayerEntity entity = pony.getMaster();
Race race = pony.getSpecies(); Race race = pony.getSpecies();

View file

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