From 18bbce8c0e2f3b91a19824adfd59c6b50203f0e8 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 9 Feb 2019 20:15:15 +0200 Subject: [PATCH] Changelings can only fly whilst disguised if they're disguised as something that can fly --- .../unicopia/player/IFlyingPredicate.java | 10 ++++++ .../unicopia/player/IGravity.java | 2 +- .../unicopia/player/IPlayer.java | 9 +++++- .../player/PlayerGravityDelegate.java | 20 ++++++++++-- .../unicopia/player/PlayerSpeciesList.java | 4 +++ .../unicopia/spell/SpellDisguise.java | 31 +++++++++++++++++-- 6 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/player/IFlyingPredicate.java diff --git a/src/main/java/com/minelittlepony/unicopia/player/IFlyingPredicate.java b/src/main/java/com/minelittlepony/unicopia/player/IFlyingPredicate.java new file mode 100644 index 00000000..3b71f6a9 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/player/IFlyingPredicate.java @@ -0,0 +1,10 @@ +package com.minelittlepony.unicopia.player; + +/** + * Predicate for abilities to control whether a player can fly. + * + * This overrides what the race specifies. + */ +public interface IFlyingPredicate { + boolean checkCanFly(IPlayer player); +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/player/IGravity.java b/src/main/java/com/minelittlepony/unicopia/player/IGravity.java index c8cb6ebd..2305102c 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/IGravity.java +++ b/src/main/java/com/minelittlepony/unicopia/player/IGravity.java @@ -1,6 +1,6 @@ package com.minelittlepony.unicopia.player; -public interface IGravity { +public interface IGravity extends IFlyingPredicate { boolean isFlying(); float getFlightExperience(); diff --git a/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java b/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java index 604de51f..0c628590 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java +++ b/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java @@ -14,6 +14,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemFood; import net.minecraft.item.ItemStack; +import net.minecraft.server.MinecraftServer; import net.minecraftforge.fml.common.FMLCommonHandler; public interface IPlayer extends ICaster, IRaceContainer, ITransmittable, IPageOwner { @@ -63,7 +64,13 @@ public interface IPlayer extends ICaster, IRaceContainer, IGravity, InbtS this.player = player; } + public boolean checkCanFly(IPlayer player) { + if (player.getOwner().capabilities.isCreativeMode) { + return true; + } + + if (player.hasEffect()) { + IMagicEffect effect = player.getEffect(); + if (!effect.getDead() && effect instanceof IFlyingPredicate) { + return ((IFlyingPredicate)effect).checkCanFly(player); + } + } + + return player.getPlayerSpecies().canFly(); + } + @Override public void onUpdate(EntityPlayer entity) { - entity.capabilities.allowFlying = entity.capabilities.isCreativeMode || player.getPlayerSpecies().canFly(); + entity.capabilities.allowFlying = checkCanFly(player); if (!entity.capabilities.isCreativeMode) { - entity.capabilities.isFlying |= entity.capabilities.allowFlying && isFlying && !entity.onGround; + entity.capabilities.isFlying |= entity.capabilities.allowFlying && isFlying && !entity.onGround && !entity.isWet(); } isFlying = entity.capabilities.isFlying && !entity.capabilities.isCreativeMode; diff --git a/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java b/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java index 9cc5a4c9..2e1906b4 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java +++ b/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java @@ -2,6 +2,8 @@ package com.minelittlepony.unicopia.player; import java.util.UUID; +import javax.annotation.Nullable; + import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.UConfig; import com.minelittlepony.unicopia.forgebullshit.FBS; @@ -66,6 +68,7 @@ public class PlayerSpeciesList { throw new IllegalArgumentException("entity"); } + @Nullable public IPlayer getPlayer(EntityPlayer player) { if (player == null) { return null; @@ -74,6 +77,7 @@ public class PlayerSpeciesList { return FBS.of(player).getPlayer(); } + @Nullable public IPlayer getPlayer(UUID playerId) { return getPlayer(IPlayer.getPlayerFromServer(playerId)); } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java index bb4ab894..66a8eb65 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java @@ -7,22 +7,25 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.UClient; -import com.minelittlepony.unicopia.mixin.MixinEntity; +import com.minelittlepony.unicopia.player.IFlyingPredicate; import com.minelittlepony.unicopia.player.IOwned; import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.mojang.authlib.GameProfile; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityFlying; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.passive.EntityAmbientCreature; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -public class SpellDisguise extends AbstractSpell { +public class SpellDisguise extends AbstractSpell implements IFlyingPredicate { @Nonnull private String entityId = ""; @@ -302,4 +305,28 @@ public class SpellDisguise extends AbstractSpell { } } } + + @Override + public boolean checkCanFly(IPlayer player) { + if (!player.getPlayerSpecies().canFly()) { + return false; + } + + if (entity != null) { + if (entity instanceof EntityFlying + || entity instanceof net.minecraft.entity.passive.EntityFlying + || entity instanceof EntityDragon + || entity instanceof EntityAmbientCreature) { + return true; + } + + if (entity instanceof IOwned) { + IPlayer iplayer = PlayerSpeciesList.instance().getPlayer(IOwned.cast(entity).getOwner()); + + return iplayer != null && iplayer.getPlayerSpecies().canFly(); + } + } + + return false; + } }