diff --git a/src/main/java/com/minelittlepony/unicopia/FlightType.java b/src/main/java/com/minelittlepony/unicopia/FlightType.java new file mode 100644 index 00000000..e2174842 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/FlightType.java @@ -0,0 +1,24 @@ +package com.minelittlepony.unicopia; + +public enum FlightType { + NONE, + CREATIVE, + AVIAN, + INSECTOID; + + public boolean isGrounded() { + return this == NONE; + } + + public boolean canFly() { + return !isGrounded(); + } + + public boolean canFlyCreative() { + return this == CREATIVE || this == INSECTOID; + } + + public boolean canFlySurvival() { + return canFly() && !canFlyCreative(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index 4eb23663..a8d457d9 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -21,21 +21,21 @@ public enum Race implements Affine { * The default, unset race. * This is used if there are no other races. */ - HUMAN(false, false, false), - EARTH(false, false, true), - UNICORN(true, false, false), - PEGASUS(false, true, false), - BAT(false, true, false), - ALICORN(true, true, true), - CHANGELING(false, true, false); + HUMAN(false, FlightType.NONE, false), + EARTH(false, FlightType.NONE, true), + UNICORN(true, FlightType.NONE, false), + PEGASUS(false, FlightType.AVIAN, false), + BAT(false, FlightType.AVIAN, false), + ALICORN(true, FlightType.AVIAN, true), + CHANGELING(false, FlightType.INSECTOID, false); private final boolean magic; - private final boolean flight; + private final FlightType flight; private final boolean earth; private final static Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Enum::ordinal, Function.identity())); - Race(boolean magic, boolean flight, boolean earth) { + Race(boolean magic, FlightType flight, boolean earth) { this.magic = magic; this.flight = flight; this.earth = earth; @@ -62,10 +62,14 @@ public enum Race implements Affine { return this == ALICORN; } - public boolean canFly() { + public FlightType getFlightType() { return flight; } + public boolean canFly() { + return !getFlightType().isGrounded(); + } + public boolean canCast() { return magic; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/FlightPredicate.java b/src/main/java/com/minelittlepony/unicopia/ability/FlightPredicate.java index ac635a5e..66532742 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/FlightPredicate.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/FlightPredicate.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability; +import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.entity.player.Pony; /** @@ -8,5 +9,5 @@ import com.minelittlepony.unicopia.entity.player.Pony; * This overrides what the race specifies. */ public interface FlightPredicate { - boolean checkCanFly(Pony player); + FlightType getFlightType(Pony player); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java index 2204db0c..e112300e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java @@ -40,11 +40,6 @@ public interface Spell extends NbtSerialisable, Affine { */ void setDirty(boolean dirty); - /** - * Returns true if this effect can be crafted into a gem. - */ - boolean isCraftable(); - /** * Gets the highest level this spell can be safely operated at. * Gems may go higher, however chance of explosion/exhaustion increases with every level. diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java index 962e78cb..a3103921 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java @@ -10,11 +10,6 @@ public abstract class AbstractSpell implements Spell { protected boolean isDead; protected boolean isDirty; - @Override - public boolean isCraftable() { - return true; - } - @Override public void setDead() { isDead = true; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java index ecc7bbb8..b4831fa1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java @@ -5,6 +5,7 @@ import java.util.Optional; import javax.annotation.Nullable; import com.minelittlepony.unicopia.Affinity; +import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.ability.FlightPredicate; import com.minelittlepony.unicopia.ability.DimensionsPredicate; @@ -37,11 +38,6 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup return "disguise"; } - @Override - public boolean isCraftable() { - return false; - } - @Override public Affinity getAffinity() { return Affinity.BAD; @@ -211,8 +207,11 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup } @Override - public boolean checkCanFly(Pony player) { - return disguise.canFly() && player.getSpecies().canFly(); + public FlightType getFlightType(Pony player) { + if (isSuppressed() || !disguise.isPresent()) { + return player.getSpecies().getFlightType(); + } + return disguise.getFlightType(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java index 264dbd77..092431a7 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java @@ -24,11 +24,6 @@ public class ScorchSpell extends FireSpell implements ThrowableSpell { return "scorch"; } - @Override - public boolean isCraftable() { - return false; - } - @Override public int getTint() { return 0; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellRegistry.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellRegistry.java index 4560af2e..266dc63f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellRegistry.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellRegistry.java @@ -157,10 +157,8 @@ public class SpellRegistry { this.color = inst.getTint(); this.affinity = inst.getAffinity(); - if (inst.isCraftable()) { - for (Affinity affinity : affinity.getImplicators()) { - keysByAffinity.computeIfAbsent(affinity, a -> new HashSet<>()).add(inst.getName()); - } + for (Affinity affinity : affinity.getImplicators()) { + keysByAffinity.computeIfAbsent(affinity, a -> new HashSet<>()).add(inst.getName()); } entries.put(inst.getName(), this); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java index e426f14b..74e255bd 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/Disguise.java @@ -8,6 +8,7 @@ import java.util.UUID; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.ability.magic.Caster; @@ -163,25 +164,29 @@ public class Disguise implements NbtSerialisable { } } - public boolean canFly() { + public FlightType getFlightType() { if (entity == null) { - return false; + return FlightType.NONE; } if (entity instanceof Owned) { @SuppressWarnings("unchecked") Pony iplayer = Pony.of(((Owned)entity).getOwner()); - return iplayer != null && iplayer.getSpecies().canFly(); + return iplayer == null ? FlightType.NONE : iplayer.getSpecies().getFlightType(); } - return entity instanceof FlyingEntity + if (entity instanceof FlyingEntity || entity instanceof AmbientEntity || entity instanceof EnderDragonEntity || entity instanceof VexEntity || entity instanceof ShulkerBulletEntity || entity instanceof Flutterer - || ProjectileUtil.isProjectile(entity); + || ProjectileUtil.isProjectile(entity)) { + return FlightType.INSECTOID; + } + + return FlightType.NONE; } public float getStandingEyeHeight() { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index e8e7cf21..af05db31 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.entity.player; +import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.FlightPredicate; @@ -79,10 +80,12 @@ public class PlayerPhysics extends EntityPhysics implements Tickable, Moti boolean creative = entity.abilities.creativeMode || pony.getOwner().isSpectator(); - boolean canFly = checkCanFly(); + FlightType type = getFlightType(); + + entity.abilities.allowFlying = type.canFlyCreative(); if (!creative) { - entity.abilities.flying |= (canFly || entity.abilities.allowFlying) && isFlyingEither; + entity.abilities.flying |= (type.canFly() || entity.abilities.allowFlying) && isFlyingEither; if ((entity.isOnGround() && entity.isSneaking()) || entity.isTouchingWater() @@ -110,7 +113,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickable, Moti } } - if (canFly) { + if (type.canFly()) { if (isFlying()) { if (pony.getSpecies() == Race.BAT && entity.verticalCollision && pony.canHangAt(pony.getOrigin().up(2))) { @@ -146,23 +149,27 @@ public class PlayerPhysics extends EntityPhysics implements Tickable, Moti } entity.fallDistance = 0; - + if (type == FlightType.AVIAN) { + applyThrust(entity, velocity); + } moveFlying(entity, velocity); if (entity.world.hasRain(entity.getBlockPos())) { applyTurbulance(entity, velocity); } - if (entity.world.isClient && ticksInAir % 20 == 0 && entity.getVelocity().length() < 0.29) { - entity.playSound(getWingSound(), 0.5F, 1); - thrustScale = 1; + if (type == FlightType.AVIAN) { + if (entity.world.isClient && ticksInAir % 20 == 0 && entity.getVelocity().length() < 0.29) { + entity.playSound(getWingSound(), 0.5F, 1); + thrustScale = 1; + } + velocity.y -= 0.02; + velocity.x *= 0.9896; + velocity.z *= 0.9896; } - velocity.y -= 0.02; - velocity.x *= 0.9896; - velocity.z *= 0.9896; } else { ticksInAir = 0; - if (!creative) { + if (!creative && type == FlightType.AVIAN) { double horMotion = getHorizontalMotion(entity); double motion = entity.getPos().subtract(lastPos).lengthSquared(); @@ -219,8 +226,6 @@ public class PlayerPhysics extends EntityPhysics implements Tickable, Moti } protected void moveFlying(PlayerEntity player, MutableVector velocity) { - applyThrust(player, velocity); - double motion = getHorizontalMotion(player); float forward = 0.000015F * (1 + (pony.getLevel().get() / 10F)) * (float)Math.sqrt(motion); @@ -292,29 +297,30 @@ public class PlayerPhysics extends EntityPhysics implements Tickable, Moti return Entity.squaredHorizontalLength(e.getPos().subtract(lastPos)); } - private boolean checkCanFly() { - if (pony.getOwner().abilities.creativeMode || pony.getOwner().isSpectator()) { - return true; + private FlightType getFlightType() { + if (pony.getOwner().isCreative() || pony.getOwner().isSpectator()) { + return FlightType.CREATIVE; } if (pony.hasSpell()) { Spell effect = pony.getSpell(true); if (!effect.isDead() && effect instanceof FlightPredicate) { - return ((FlightPredicate)effect).checkCanFly(pony); + return ((FlightPredicate)effect).getFlightType(pony); } } - return pony.getSpecies().canFly(); + return pony.getSpecies().getFlightType(); } public void updateFlightStat(boolean flying) { PlayerEntity entity = pony.getOwner(); - boolean canFly = checkCanFly(); + FlightType type = getFlightType(); - if (canFly || entity.abilities.allowFlying) { + entity.abilities.allowFlying = type.canFlyCreative(); + + if (type.canFly() || entity.abilities.allowFlying) { entity.abilities.flying |= flying; - isFlyingSurvival = entity.abilities.flying; } else { entity.abilities.flying = false;