Implement different flight types

This commit is contained in:
Sollace 2020-10-08 09:39:30 +02:00
parent 6f2ef7719a
commit 629f30be0e
10 changed files with 85 additions and 63 deletions

View file

@ -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();
}
}

View file

@ -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<Integer, Race> 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;
}

View file

@ -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);
}

View file

@ -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.

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -157,11 +157,9 @@ 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());
}
}
entries.put(inst.getName(), this);
}

View file

@ -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<PlayerEntity>)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() {

View file

@ -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<Pony> 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<Pony> implements Tickable, Moti
}
}
if (canFly) {
if (type.canFly()) {
if (isFlying()) {
if (pony.getSpecies() == Race.BAT && entity.verticalCollision && pony.canHangAt(pony.getOrigin().up(2))) {
@ -146,12 +149,15 @@ public class PlayerPhysics extends EntityPhysics<Pony> 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 (type == FlightType.AVIAN) {
if (entity.world.isClient && ticksInAir % 20 == 0 && entity.getVelocity().length() < 0.29) {
entity.playSound(getWingSound(), 0.5F, 1);
thrustScale = 1;
@ -159,10 +165,11 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
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<Pony> 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<Pony> 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;