Added mana and mana bars

This commit is contained in:
Sollace 2020-10-01 17:04:48 +02:00
parent dd2e2a1f81
commit 8025cf570b
16 changed files with 264 additions and 197 deletions

View file

@ -25,13 +25,20 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
@Nullable @Nullable
@Override @Override
public Hit tryActivate(Pony player) { public Hit tryActivate(Pony player) {
if (player.getMagicalReserves().getMana().getPercentFill() >= 0.9F) {
return Hit.INSTANCE; return Hit.INSTANCE;
} }
return null;
}
@Override @Override
public void apply(Pony iplayer, Hit data) { public void apply(Pony iplayer, Hit data) {
PlayerEntity player = iplayer.getOwner(); PlayerEntity player = iplayer.getOwner();
if (iplayer.getMagicalReserves().getMana().getPercentFill() < 0.9F) {
return;
}
RayTraceHelper.Trace trace = RayTraceHelper.doTrace(player, 10, 1, EntityPredicates.EXCEPT_SPECTATOR.and(e -> !(e instanceof LightningEntity))); RayTraceHelper.Trace trace = RayTraceHelper.doTrace(player, 10, 1, EntityPredicates.EXCEPT_SPECTATOR.and(e -> !(e instanceof LightningEntity)));
Entity looked = trace.getEntity().map(e -> { Entity looked = trace.getEntity().map(e -> {
@ -56,19 +63,21 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
return disc; return disc;
}).setDisguise(looked); }).setDisguise(looked);
iplayer.getMagicalReserves().getMana().multiply(0.1F);
player.calculateDimensions(); player.calculateDimensions();
iplayer.setDirty(); iplayer.setDirty();
} }
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addEnergy(20); player.getMagicalReserves().getEnergy().add(20);
player.spawnParticles(UParticles.CHANGELING_MAGIC, 5); player.spawnParticles(UParticles.CHANGELING_MAGIC, 5);
} }
@Override @Override
public void postApply(Pony player, AbilitySlot slot) { public void postApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().setEnergy(0); player.getMagicalReserves().getEnergy().set(0);
player.spawnParticles(UParticles.CHANGELING_MAGIC, 5); player.spawnParticles(UParticles.CHANGELING_MAGIC, 5);
} }
} }

View file

@ -149,7 +149,7 @@ public class ChangelingFeedAbility implements Ability<Hit> {
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addExertion(6); player.getMagicalReserves().getExertion().add(6);
} }
@Override @Override

View file

@ -73,7 +73,7 @@ public class EarthPonyGrowAbility implements Ability<Pos> {
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addExertion(30); player.getMagicalReserves().getExertion().add(30);
if (player.getWorld().isClient()) { if (player.getWorld().isClient()) {
player.spawnParticles(MagicParticleEffect.UNICORN, 1); player.spawnParticles(MagicParticleEffect.UNICORN, 1);

View file

@ -184,7 +184,7 @@ public class EarthPonyStompAbility implements Ability<Multi> {
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addExertion(40); player.getMagicalReserves().getExertion().add(40);
} }
@Override @Override

View file

@ -62,7 +62,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addEnergy(3); player.getMagicalReserves().getEnergy().add(3);
player.spawnParticles(MagicParticleEffect.UNICORN, 5); player.spawnParticles(MagicParticleEffect.UNICORN, 5);
} }

View file

@ -45,7 +45,8 @@ public class UnicornTeleportAbility implements Ability<Pos> {
@Override @Override
public Pos tryActivate(Pony player) { public Pos tryActivate(Pony player) {
HitResult ray = RayTraceHelper.doTrace(player.getOwner(), 100, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult(); int maxDistance = player.getOwner().isCreative() ? 1000 : 100;
HitResult ray = RayTraceHelper.doTrace(player.getOwner(), maxDistance, 1, EntityPredicates.EXCEPT_SPECTATOR).getResult();
World w = player.getWorld(); World w = player.getWorld();
@ -152,7 +153,7 @@ public class UnicornTeleportAbility implements Ability<Pos> {
@Override @Override
public void preApply(Pony player, AbilitySlot slot) { public void preApply(Pony player, AbilitySlot slot) {
player.getMagicalReserves().addExertion(30); player.getMagicalReserves().getExertion().add(30);
player.spawnParticles(MagicParticleEffect.UNICORN, 5); player.spawnParticles(MagicParticleEffect.UNICORN, 5);
} }

View file

@ -81,17 +81,19 @@ class Slot {
} }
// contents // contents
//int middle = (slotPadding + size - iconSize)/2;
uHud.renderAbilityIcon(matrices, stat, slotPadding / 2, slotPadding / 2, iconSize, iconSize, iconSize, iconSize); uHud.renderAbilityIcon(matrices, stat, slotPadding / 2, slotPadding / 2, iconSize, iconSize, iconSize, iconSize);
// foreground
UHud.drawTexture(matrices, 0, 0, backgroundU, backgroundV, size, size, 128, 128);
matrices.pop(); matrices.pop();
} }
void renderForeground(MatrixStack matrices, AbilityDispatcher abilities, float tickDelta) { void renderForeground(MatrixStack matrices, AbilityDispatcher abilities, float tickDelta) {
matrices.push();
matrices.translate(x, y, 0);
UHud.drawTexture(matrices, 0, 0, backgroundU, backgroundV, size, size, 128, 128);
matrices.pop();
}
void renderLabel(MatrixStack matrices, AbilityDispatcher abilities, float tickDelta) {
Text label = KeyBindingsHandler.INSTANCE.getBinding(aSlot).getBoundKeyLocalizedText(); Text label = KeyBindingsHandler.INSTANCE.getBinding(aSlot).getBoundKeyLocalizedText();
matrices.push(); matrices.push();

View file

@ -6,6 +6,7 @@ import java.util.List;
import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.ability.Abilities;
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.entity.player.MagicReserves.Bar;
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,9 +14,15 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; 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.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
public class UHud extends DrawableHelper { public class UHud extends DrawableHelper {
@ -57,8 +64,13 @@ public class UHud extends DrawableHelper {
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));
renderManaRings(matrices);
slots.forEach(slot -> slot.renderForeground(matrices, abilities, tickDelta)); slots.forEach(slot -> slot.renderForeground(matrices, abilities, tickDelta));
slots.forEach(slot -> slot.renderLabel(matrices, abilities, tickDelta));
RenderSystem.disableBlend(); RenderSystem.disableBlend();
RenderSystem.disableAlphaTest(); RenderSystem.disableAlphaTest();
@ -75,4 +87,74 @@ public class UHud extends DrawableHelper {
client.getTextureManager().bindTexture(HUD_TEXTURE); client.getTextureManager().bindTexture(HUD_TEXTURE);
}); });
} }
void renderManaRings(MatrixStack matrices) {
matrices.push();
matrices.translate(24.5, 25.5, 0);
Bar mana = Pony.of(client.player).getMagicalReserves().getMana();
Bar exer = Pony.of(client.player).getMagicalReserves().getEnergy();
renderRing(matrices, 17, 13, MathHelper.lerp(client.getTickDelta(), mana.getPrev(), mana.get()) / mana.getMax(), 0xFF88FF99);
renderRing(matrices, 17, 13, MathHelper.lerp(client.getTickDelta(), exer.getPrev(), exer.get()) / exer.getMax(), 0xFF002299);
matrices.pop();
}
static void renderRing(MatrixStack matrices, double outerRadius, double innerRadius, double maxAngle, int color) {
float f = (color >> 24 & 255) / 255.0F;
float g = (color >> 16 & 255) / 255.0F;
float h = (color >> 8 & 255) / 255.0F;
float k = (color & 255) / 255.0F;
final double num_rings = 300;
double twoPi = Math.PI * 2;
final double increment = twoPi / num_rings;
maxAngle *= twoPi;
maxAngle = MathHelper.clamp(maxAngle, 0, twoPi - increment);
if (maxAngle < increment) {
return;
}
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.enableBlend();
RenderSystem.disableTexture();
RenderSystem.defaultBlendFunc();
bufferBuilder.begin(7, VertexFormats.POSITION_COLOR);
Matrix4f model = matrices.peek().getModel();
for (double angle = 0; angle >= -maxAngle; angle -= increment) {
// center
bufferBuilder.vertex(model,
(float)(innerRadius * Math.sin(angle)),
(float)(innerRadius * Math.cos(angle)), 0).color(f, g, h, k).next();
// point one
bufferBuilder.vertex(model,
(float)(outerRadius * Math.sin(angle)),
(float)(outerRadius * Math.cos(angle)), 0).color(f, g, h, 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();
// 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();
}
bufferBuilder.end();
BufferRenderer.draw(bufferBuilder);
RenderSystem.enableTexture();
}
} }

View file

@ -79,7 +79,7 @@ public class SphereModel {
drawVertex(model, vertexWriter, radius, zenith, azimuth + azimuthIncrement, light, overlay, r, g, b, a); drawVertex(model, vertexWriter, radius, zenith, azimuth + azimuthIncrement, light, overlay, r, g, b, a);
} }
protected void drawVertex(Matrix4f model, VertexConsumer vertexWriter, public static void drawVertex(Matrix4f model, VertexConsumer vertexWriter,
double radius, double zenith, double azimuth, double radius, double zenith, double azimuth,
int light, int overlay, float r, float g, float b, float a) { int light, int overlay, float r, float g, float b, float a) {
Vector4f position = convertToCartesianCoord(radius, zenith, azimuth); Vector4f position = convertToCartesianCoord(radius, zenith, azimuth);
@ -87,7 +87,7 @@ public class SphereModel {
vertexWriter.vertex(position.getX(), position.getY(), position.getZ(), r, g, b, a, 0, 0, overlay, light, 0, 0, 0); vertexWriter.vertex(position.getX(), position.getY(), position.getZ(), r, g, b, a, 0, 0, overlay, light, 0, 0, 0);
} }
protected Vector4f convertToCartesianCoord(double r, double theta, double phi) { public static Vector4f convertToCartesianCoord(double r, double theta, double phi) {
double x = r * Math.sin(theta) * Math.cos(phi); double x = r * Math.sin(theta) * Math.cos(phi);
double y = r * Math.sin(theta) * Math.sin(phi); double y = r * Math.sin(theta) * Math.sin(phi);

View file

@ -91,8 +91,8 @@ public class RaceChangeStatusEffect extends StatusEffect {
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
Pony pony = (Pony)eq; Pony pony = (Pony)eq;
MagicReserves magic = pony.getMagicalReserves(); MagicReserves magic = pony.getMagicalReserves();
magic.addExertion(50); magic.getExertion().add(50);
magic.addEnergy(3); magic.getEnergy().add(3);
if (state.shouldShowParticles()) { if (state.shouldShowParticles()) {
pony.spawnParticles(ParticleTypes.TOTEM_OF_UNDYING, 5); pony.spawnParticles(ParticleTypes.TOTEM_OF_UNDYING, 5);

View file

@ -1,40 +1,69 @@
package com.minelittlepony.unicopia.entity.player; package com.minelittlepony.unicopia.entity.player;
public interface MagicReserves { public interface MagicReserves {
/** /**
* Gets the amount of exertion this player has put toward any given activity. * Gets the amount of exertion this player has put toward any given activity.
* This is simillar to tiredness. * This is simillar to tiredness.
*/ */
float getExertion(); Bar getExertion();
/**
* Sets the player's exertion level.
*/
void setExertion(float exertion);
/**
* Adds player tiredness.
*/
default void addExertion(int exertion) {
setExertion(getExertion() + exertion/100F);
}
/** /**
* Gets the amount of excess energy the player has. * Gets the amount of excess energy the player has.
* This is increased by eating sugar. * This is increased by eating sugar.
*/ */
float getEnergy(); Bar getEnergy();
/** /**
* Sets the player's energy level. * Gets the amount of magical energy the player has.
* This is increases slowly with time by performing certain actions.
*/ */
void setEnergy(float energy); Bar getMana();
public interface Bar {
/** /**
* Adds energy to the player's existing energy level. * Gets the current value of this bar
*/ */
default void addEnergy(int energy) { float get();
setEnergy(getEnergy() + energy / 100F);
/**
* Gets the previous value from the last tick.
* Only updated when calling getPrev again.
*/
float getPrev();
/**
* Sets the absolute value
*/
void set(float value);
/**
* Gets the percentage fill of this bar
*/
default float getPercentFill() {
return get() / getMax();
} }
/**
* Adds a percentage increment to this bar's current value
*/
default void add(int step) {
set(get() + (step / getMax()));
}
/**
* Multiplies the current value.
*/
default void multiply(float scalar) {
set(get() * scalar);
}
/**
* Get the maximum value this bar is allowed to contain
*/
default float getMax() {
return 100F;
}
}
} }

View file

@ -1,32 +1,62 @@
package com.minelittlepony.unicopia.entity.player; package com.minelittlepony.unicopia.entity.player;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.util.math.MathHelper;
public class ManaContainer implements MagicReserves { public class ManaContainer implements MagicReserves {
private final Pony pony; private final Pony pony;
private final Bar energy;
private final Bar exertion;
private final Bar mana;
public ManaContainer(Pony pony) { public ManaContainer(Pony pony) {
this.pony = pony; this.pony = pony;
pony.getOwner().getDataTracker().startTracking(Pony.ENERGY, 0F); this.energy = new BarInst(Pony.ENERGY);
pony.getOwner().getDataTracker().startTracking(Pony.EXERTION, 0F); this.exertion = new BarInst(Pony.EXERTION);
this.mana = new BarInst(Pony.MANA);
} }
@Override @Override
public float getExertion() { public Bar getExertion() {
return pony.getOwner().getDataTracker().get(Pony.EXERTION); return exertion;
} }
@Override @Override
public void setExertion(float exertion) { public Bar getEnergy() {
pony.getOwner().getDataTracker().set(Pony.EXERTION, Math.max(0, exertion)); return energy;
} }
@Override @Override
public float getEnergy() { public Bar getMana() {
return pony.getOwner().getDataTracker().get(Pony.ENERGY); return mana;
}
class BarInst implements Bar {
private final TrackedData<Float> marker;
private float prev;
BarInst(TrackedData<Float> marker) {
this.marker = marker;
pony.getOwner().getDataTracker().startTracking(marker, 0F);
} }
@Override @Override
public void setEnergy(float energy) { public float get() {
pony.getOwner().getDataTracker().set(Pony.ENERGY, Math.max(0, energy)); return pony.getOwner().getDataTracker().get(marker);
} }
@Override
public float getPrev() {
float value = prev;
prev = get();
return value;
}
@Override
public void set(float value) {
pony.getOwner().getDataTracker().set(marker, MathHelper.clamp(value, 0, getMax()));
}
}
} }

View file

@ -9,11 +9,5 @@ public interface Motion {
*/ */
boolean isFlying(); boolean isFlying();
float getFlightExperience();
float getFlightDuration();
boolean isExperienceCritical();
PlayerDimensions getDimensions(); PlayerDimensions getDimensions();
} }

View file

@ -45,14 +45,14 @@ public class PlayerCamera extends MotionCompositor {
} }
public double calculateFieldOfView(double fov) { public double calculateFieldOfView(double fov) {
fov += player.getMagicalReserves().getExertion() / 5F; fov += player.getMagicalReserves().getExertion().get() / 5F;
fov += getEnergyAddition(); fov += getEnergyAddition();
return fov; return fov;
} }
protected float getEnergyAddition() { protected float getEnergyAddition() {
int maxE = (int)Math.floor(player.getMagicalReserves().getEnergy() * 100); int maxE = (int)Math.floor(player.getMagicalReserves().getEnergy().get() * 100);
if (maxE <= 0) { if (maxE <= 0) {
return 0; return 0;

View file

@ -1,13 +1,11 @@
package com.minelittlepony.unicopia.entity.player; package com.minelittlepony.unicopia.entity.player;
import java.util.Random;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
import com.minelittlepony.unicopia.ability.FlightPredicate; import com.minelittlepony.unicopia.ability.FlightPredicate;
import com.minelittlepony.unicopia.ability.magic.Spell; import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.entity.EntityPhysics; import com.minelittlepony.unicopia.entity.EntityPhysics;
import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.MutableVector; import com.minelittlepony.unicopia.util.MutableVector;
@ -21,18 +19,13 @@ import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Tickable; import net.minecraft.util.Tickable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Motion, NbtSerialisable { public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Motion, NbtSerialisable {
private static final float MAXIMUM_FLIGHT_EXPERIENCE = 1500; private int ticksInAir;
public int ticksNextLevel = 0;
public float flightExperience = 0;
public boolean isFlyingEither = false; public boolean isFlyingEither = false;
public boolean isFlyingSurvival = false; public boolean isFlyingSurvival = false;
public boolean isRainbooming = false;
private double lastTickPosX = 0; private double lastTickPosX = 0;
private double lastTickPosZ = 0; private double lastTickPosZ = 0;
@ -78,11 +71,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
return dimensions; return dimensions;
} }
@Override
public boolean isExperienceCritical() {
return isRainbooming || flightExperience > MAXIMUM_FLIGHT_EXPERIENCE * 0.8;
}
@Override @Override
public void tick() { public void tick() {
PlayerEntity entity = pony.getOwner(); PlayerEntity entity = pony.getOwner();
@ -97,20 +85,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
MutableVector velocity = new MutableVector(entity.getVelocity()); MutableVector velocity = new MutableVector(entity.getVelocity());
if (isExperienceCritical() && pony.isClient()) {
Random rnd = pony.getWorld().random;
for (int i = 0; i < 360 + getHorizontalMotion(entity); i += 10) {
Vec3d pos = pony.getOriginVector().add(
rnd.nextGaussian() * entity.getWidth(),
rnd.nextGaussian() * entity.getHeight()/2,
rnd.nextGaussian() * entity.getWidth()
);
pony.addParticle(MagicParticleEffect.UNICORN, pos, velocity.toImmutable());
}
}
boolean creative = entity.abilities.creativeMode || pony.getOwner().isSpectator(); boolean creative = entity.abilities.creativeMode || pony.getOwner().isSpectator();
entity.abilities.allowFlying = checkCanFly(); entity.abilities.allowFlying = checkCanFly();
@ -121,72 +95,44 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
if ((entity.isOnGround() && entity.isSneaking()) || entity.isTouchingWater()) { if ((entity.isOnGround() && entity.isSneaking()) || entity.isTouchingWater()) {
entity.abilities.flying = false; entity.abilities.flying = false;
} }
} }
isFlyingSurvival = entity.abilities.flying && !creative; isFlyingSurvival = entity.abilities.flying && !creative;
isFlyingEither = isFlyingSurvival || (creative && entity.abilities.flying); isFlyingEither = isFlyingSurvival || (creative && entity.abilities.flying);
if (!creative && !entity.isFallFlying()) { if (!creative && !entity.isFallFlying() && isFlyingSurvival && !entity.hasVehicle()) {
if (isFlyingSurvival && !entity.hasVehicle()) {
if (!isRainbooming && getHorizontalMotion(entity) > 0.2 && flightExperience < MAXIMUM_FLIGHT_EXPERIENCE) {
flightExperience++;
}
entity.fallDistance = 0; entity.fallDistance = 0;
if (pony.getSpecies() != Race.CHANGELING && entity.world.random.nextInt(100) == 0) { if (ticksInAir > 100) {
float exhaustion = (0.3F * ticksNextLevel) / 70; Bar mana = pony.getMagicalReserves().getMana();
mana.add((int)(-getHorizontalMotion(entity) * 100));
if (mana.getPercentFill() < 0.2) {
pony.getMagicalReserves().getExertion().add(2);
pony.getMagicalReserves().getEnergy().add(2);
if (mana.getPercentFill() < 0.1 && ticksInAir % 10 == 0) {
float exhaustion = (0.3F * ticksInAir) / 70;
if (entity.isSprinting()) { if (entity.isSprinting()) {
exhaustion *= 3.11F; exhaustion *= 3.11F;
} }
exhaustion *= (1 - flightExperience / MAXIMUM_FLIGHT_EXPERIENCE);
entity.addExhaustion(exhaustion); entity.addExhaustion(exhaustion);
} }
}
if (ticksNextLevel++ >= MAXIMUM_FLIGHT_EXPERIENCE) {
ticksNextLevel = 0;
entity.addExperience(1);
addFlightExperience(1);
entity.playSound(SoundEvents.ENTITY_GUARDIAN_FLOP, 1, 1);
} }
moveFlying(entity, velocity); moveFlying(entity, velocity);
if (isExperienceCritical()) { if (ticksInAir++ > 0 && ticksInAir % 30 == 0) {
if (pony.getMagicalReserves().getEnergy() <= 0.25F) {
pony.getMagicalReserves().addEnergy(2);
}
if (isRainbooming || (entity.isSneaking() && isRainboom())) {
performRainboom(entity, velocity);
}
}
if (ticksNextLevel > 0 && ticksNextLevel % 30 == 0) {
entity.playSound(getWingSound(), 0.5F, 1); entity.playSound(getWingSound(), 0.5F, 1);
} }
} else { } else {
if (ticksNextLevel != 0) { ticksInAir = 0;
entity.playSound(getWingSound(), 0.4F, 1);
}
ticksNextLevel = 0;
if (isExperienceCritical()) {
addFlightExperience(-0.39991342F);
} else {
addFlightExperience(-0.019991342F);
}
if (flightExperience < 0.02) {
isRainbooming = false;
}
}
} }
if (pony.getPhysics().isGravityNegative()) { if (pony.getPhysics().isGravityNegative()) {
@ -208,28 +154,9 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
return pony.getSpecies() == Race.CHANGELING ? USounds.CHANGELING_BUZZ : USounds.WING_FLAP; return pony.getSpecies() == Race.CHANGELING ? USounds.CHANGELING_BUZZ : USounds.WING_FLAP;
} }
protected void performRainboom(Entity entity, MutableVector velocity) {
float forward = 0.5F * flightExperience / MAXIMUM_FLIGHT_EXPERIENCE;
velocity.x += - forward * MathHelper.sin(entity.yaw * 0.017453292F);
velocity.z += forward * MathHelper.cos(entity.yaw * 0.017453292F);
velocity.y += forward * MathHelper.sin(entity.pitch * 0.017453292F);
if (!isRainbooming || entity.world.random.nextInt(5) == 0) {
entity.playSound(SoundEvents.ENTITY_LIGHTNING_BOLT_THUNDER, 1, 1);
}
if (flightExperience > 0) {
flightExperience -= 13;
isRainbooming = true;
} else {
isRainbooming = false;
}
}
protected void moveFlying(Entity player, MutableVector velocity) { protected void moveFlying(Entity player, MutableVector velocity) {
float forward = 0.000015F * flightExperience * (float)Math.sqrt(getHorizontalMotion(player)); float forward = 0.000015F * (float)Math.sqrt(getHorizontalMotion(player));
boolean sneak = !player.isSneaking(); boolean sneak = !player.isSneaking();
// vertical drop due to gravity // vertical drop due to gravity
@ -287,13 +214,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
return distance > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL; return distance > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL;
} }
private void addFlightExperience(float factor) {
float maximumGain = MAXIMUM_FLIGHT_EXPERIENCE - flightExperience;
float gainSteps = 20;
flightExperience = Math.max(0, flightExperience + factor * maximumGain / gainSteps);
}
public void updateFlightStat(boolean flying) { public void updateFlightStat(boolean flying) {
PlayerEntity entity = pony.getOwner(); PlayerEntity entity = pony.getOwner();
@ -303,10 +223,6 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
entity.abilities.flying |= flying; entity.abilities.flying |= flying;
isFlyingSurvival = entity.abilities.flying; isFlyingSurvival = entity.abilities.flying;
if (isFlyingSurvival) {
ticksNextLevel = 0;
}
} else { } else {
entity.abilities.flying = false; entity.abilities.flying = false;
isFlyingSurvival = false; isFlyingSurvival = false;
@ -316,21 +232,17 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
@Override @Override
public void toNBT(CompoundTag compound) { public void toNBT(CompoundTag compound) {
super.toNBT(compound); super.toNBT(compound);
compound.putInt("flightDuration", ticksNextLevel);
compound.putFloat("flightExperience", flightExperience);
compound.putBoolean("isFlying", isFlyingSurvival); compound.putBoolean("isFlying", isFlyingSurvival);
compound.putBoolean("isFlyingEither", isFlyingEither); compound.putBoolean("isFlyingEither", isFlyingEither);
compound.putBoolean("isRainbooming", isRainbooming); compound.putInt("ticksInAir", ticksInAir);
} }
@Override @Override
public void fromNBT(CompoundTag compound) { public void fromNBT(CompoundTag compound) {
super.fromNBT(compound); super.fromNBT(compound);
ticksNextLevel = compound.getInt("flightDuration");
flightExperience = compound.getFloat("flightExperience");
isFlyingSurvival = compound.getBoolean("isFlying"); isFlyingSurvival = compound.getBoolean("isFlying");
isFlyingEither = compound.getBoolean("isFlyingEither"); isFlyingEither = compound.getBoolean("isFlyingEither");
isRainbooming = compound.getBoolean("isRainbooming"); ticksInAir = compound.getInt("ticksInAir");
pony.getOwner().calculateDimensions(); pony.getOwner().calculateDimensions();
} }
@ -339,14 +251,4 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
public boolean isFlying() { public boolean isFlying() {
return isFlyingSurvival; return isFlyingSurvival;
} }
@Override
public float getFlightExperience() {
return flightExperience / MAXIMUM_FLIGHT_EXPERIENCE;
}
@Override
public float getFlightDuration() {
return ticksNextLevel / MAXIMUM_FLIGHT_EXPERIENCE;
}
} }

View file

@ -54,8 +54,11 @@ 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> {
private static final TrackedData<Integer> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final TrackedData<Integer> RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); static final TrackedData<Float> EXERTION = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
static final TrackedData<Float> MANA = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final TrackedData<CompoundTag> HELD_EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND); private static final TrackedData<CompoundTag> HELD_EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
@ -273,8 +276,12 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
} }
} }
mana.addExertion(-10); mana.getExertion().add(-10);
mana.addEnergy(-1); mana.getEnergy().add(-1);
if (!getSpecies().canFly() || !gravity.isFlying()) {
mana.getMana().add(60);
}
attributes.applyAttributes(this); attributes.applyAttributes(this);
@ -323,6 +330,16 @@ 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.abilities.creativeMode) {
float currentMana = mana.getMana().get();
float foodManaRatio = 10;
if (currentMana >= foodSubtract * foodManaRatio) {
mana.getMana().set(currentMana - (float)foodSubtract * foodManaRatio);
} else {
mana.getMana().set(0);
foodSubtract -= currentMana / foodManaRatio;
int food = (int)(entity.getHungerManager().getFoodLevel() - foodSubtract); int food = (int)(entity.getHungerManager().getFoodLevel() - foodSubtract);
if (food < 0) { if (food < 0) {
@ -332,6 +349,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
entity.getHungerManager().add((int)-foodSubtract, 0); entity.getHungerManager().add((int)-foodSubtract, 0);
} }
} }
}
return entity.getHealth() > 0; return entity.getHealth() > 0;
} }