Changelings can now disguise themselves as other players

This commit is contained in:
Sollace 2019-02-09 16:34:17 +02:00
parent 10ed8fe920
commit 70ab3a025d
9 changed files with 160 additions and 45 deletions

View file

@ -7,6 +7,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.minelittlepony.jumpingcastle.api.Target; import com.minelittlepony.jumpingcastle.api.Target;
import com.minelittlepony.unicopia.entity.EntityFakeClientPlayer;
import com.minelittlepony.unicopia.hud.UHud; import com.minelittlepony.unicopia.hud.UHud;
import com.minelittlepony.unicopia.input.Keyboard; import com.minelittlepony.unicopia.input.Keyboard;
import com.minelittlepony.unicopia.inventory.gui.GuiOfHolding; import com.minelittlepony.unicopia.inventory.gui.GuiOfHolding;
@ -22,10 +23,10 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiOptions; import net.minecraft.client.gui.GuiOptions;
import net.minecraft.client.gui.GuiShareToLan;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
@ -110,10 +111,7 @@ public class UnicopiaClient extends UClient {
@Nonnull @Nonnull
public EntityPlayer createPlayer(Entity observer, GameProfile profile) { public EntityPlayer createPlayer(Entity observer, GameProfile profile) {
if (!observer.world.isRemote) { return new EntityFakeClientPlayer(observer.world, profile);
return super.createPlayer(observer, profile);
}
return new EntityOtherPlayerMP(observer.world, profile);
} }
@Override @Override
@ -137,7 +135,7 @@ public class UnicopiaClient extends UClient {
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@SubscribeEvent @SubscribeEvent
public static void onDisplayGui(GuiScreenEvent.InitGuiEvent.Post event) { public static void onDisplayGui(GuiScreenEvent.InitGuiEvent.Post event) {
if (event.getGui() instanceof GuiOptions) { if (event.getGui() instanceof GuiOptions || event.getGui() instanceof GuiShareToLan) {
addUniButton(event); addUniButton(event);
} }
} }
@ -198,24 +196,28 @@ public class UnicopiaClient extends UClient {
if (iplayer.hasEffect()) { if (iplayer.hasEffect()) {
RenderManager renderMan = Minecraft.getMinecraft().getRenderManager(); RenderManager renderMan = Minecraft.getMinecraft().getRenderManager();
IMagicEffect effect = iplayer.getEffect(); IMagicEffect effect = iplayer.getEffect(false);
if (!effect.getDead() && effect instanceof SpellDisguise) { if (!effect.getDead() && effect instanceof SpellDisguise) {
Entity e = ((SpellDisguise)effect).getDisguise(); Entity e = ((SpellDisguise)effect).getDisguise();
if (renderMan.isRenderShadow() && !(e instanceof EntityPlayer)) { if (renderMan.isRenderShadow() && !(e instanceof EntityPlayer)) {
return; return;
} }
effect.update(iplayer);
// Check for a disguise and render it in our place. // Check for a disguise and render it in our place.
if (e != null) { if (e != null) {
e.setInvisible(false); e.setInvisible(false);
renderMan.renderEntity(e, 0, 0, 0, 0, 1, false);
float partialTicks = Minecraft.getMinecraft().getRenderPartialTicks();
if (renderMan.isRenderShadow()) {
renderMan.renderEntityStatic(e, partialTicks, false);
} else {
e.setAlwaysRenderNameTag(false);
effect.update(iplayer);
renderMan.renderEntity(e, 0, 0, 0, 0, 1, false);
}
} }
} }
} }

View file

@ -0,0 +1,77 @@
package com.minelittlepony.unicopia.entity;
import java.util.UUID;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.player.IOwned;
import com.mojang.authlib.GameProfile;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
public class EntityFakeClientPlayer extends AbstractClientPlayer implements IOwned<UUID> {
private final GameProfile profile;
private NetworkPlayerInfo playerInfo;
private UUID owner;
public EntityFakeClientPlayer(World world, GameProfile profile) {
super(world, profile);
this.profile = profile;
}
@Nullable
protected NetworkPlayerInfo getPlayerInfo() {
if (playerInfo == null) {
playerInfo = new NetworkPlayerInfo(profile);
}
return playerInfo;
}
@Override
public boolean isPlayer() {
return false;
}
@Override
protected void playEquipSound(ItemStack stack) {
/*noop*/
}
@Override
public boolean isUser() {
return false;
}
@Override
public boolean getAlwaysRenderNameTagForRender() {
return !(Minecraft.getMinecraft().player != null
&& Minecraft.getMinecraft().player.getGameProfile().getId().equals(getOwner()));
}
@Override
public UUID getOwner() {
return owner;
}
@Override
public void setOwner(UUID owner) {
this.owner = owner;
}
@Override
public ITextComponent getDisplayName() {
ITextComponent name = super.getDisplayName();
name.getStyle().setItalic(true);
return name;
}
}

View file

@ -91,8 +91,8 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
@Nullable @Nullable
@Override @Override
public IMagicEffect getEffect() { public IMagicEffect getEffect(boolean update) {
return effectDelegate.get(); return effectDelegate.get(update);
} }
@Override @Override

View file

@ -55,7 +55,11 @@ public class EffectSync<T extends EntityLivingBase> {
return effect != null; return effect != null;
} }
public IMagicEffect get() { public IMagicEffect get(boolean update) {
if (!update) {
return effect;
}
NBTTagCompound comp = owned.getEntity().getDataManager().get(param); NBTTagCompound comp = owned.getEntity().getDataManager().get(param);
if (comp == null || !comp.hasKey("effect_id")) { if (comp == null || !comp.hasKey("effect_id")) {

View file

@ -2,10 +2,13 @@ package com.minelittlepony.unicopia.player;
public interface IOwned<E> { public interface IOwned<E> {
default void setOwner(E owner) { void setOwner(E owner);
}
E getOwner(); E getOwner();
@SuppressWarnings("unchecked")
static <T> IOwned<T> cast(Object o) {
return (IOwned<T>)o;
}
} }

View file

@ -351,8 +351,8 @@ class PlayerCapabilities implements IPlayer {
@Nullable @Nullable
@Override @Override
public IMagicEffect getEffect() { public IMagicEffect getEffect(boolean update) {
return effectDelegate.get(); return effectDelegate.get(update);
} }
@Override @Override

View file

@ -1,9 +1,12 @@
package com.minelittlepony.unicopia.power; package com.minelittlepony.unicopia.power;
import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
import com.minelittlepony.unicopia.UClient;
import com.minelittlepony.unicopia.UParticles; import com.minelittlepony.unicopia.UParticles;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
@ -11,6 +14,7 @@ import com.minelittlepony.unicopia.power.data.Hit;
import com.minelittlepony.unicopia.spell.IMagicEffect; import com.minelittlepony.unicopia.spell.IMagicEffect;
import com.minelittlepony.unicopia.spell.SpellDisguise; import com.minelittlepony.unicopia.spell.SpellDisguise;
import com.minelittlepony.util.vector.VecHelper; import com.minelittlepony.util.vector.VecHelper;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;

View file

@ -23,7 +23,12 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelle
void setEffect(@Nullable IMagicEffect effect); void setEffect(@Nullable IMagicEffect effect);
@Nullable @Nullable
IMagicEffect getEffect(); IMagicEffect getEffect(boolean update);
@Nullable
default IMagicEffect getEffect() {
return getEffect(true);
}
boolean hasEffect(); boolean hasEffect();

View file

@ -7,6 +7,7 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.UClient; import com.minelittlepony.unicopia.UClient;
import com.minelittlepony.unicopia.player.IOwned;
import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.IPlayer;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -17,6 +18,7 @@ import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
public class SpellDisguise extends AbstractSpell { public class SpellDisguise extends AbstractSpell {
@ -87,6 +89,7 @@ public class SpellDisguise extends AbstractSpell {
return this; return this;
} }
@SuppressWarnings("unchecked")
@Override @Override
public boolean update(ICaster<?> source) { public boolean update(ICaster<?> source) {
if (entity == null && entityNbt != null) { if (entity == null && entityNbt != null) {
@ -97,6 +100,7 @@ public class SpellDisguise extends AbstractSpell {
entityNbt.getString("playerName")); entityNbt.getString("playerName"));
entity = UClient.instance().createPlayer(source.getEntity(), profile); entity = UClient.instance().createPlayer(source.getEntity(), profile);
entity.setCustomNameTag(source.getOwner().getName());
entity.setUniqueId(UUID.randomUUID()); entity.setUniqueId(UUID.randomUUID());
entity.readFromNBT(entityNbt.getCompoundTag("playerNbt")); entity.readFromNBT(entityNbt.getCompoundTag("playerNbt"));
PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).setEffect(null);; PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).setEffect(null);;
@ -121,10 +125,27 @@ public class SpellDisguise extends AbstractSpell {
entity.onGround = owner.onGround; entity.onGround = owner.onGround;
entity.onUpdate(); entity.onUpdate();
if (entity instanceof EntityLiving) { entity.copyLocationAndAnglesFrom(owner);
EntityLiving l = (EntityLiving)entity;
l.setNoAI(true); entity.setNoGravity(true);
entity.prevPosX = owner.prevPosX;
entity.prevPosY = owner.prevPosY;
entity.prevPosZ = owner.prevPosZ;
entity.motionX = owner.motionX;
entity.motionY = owner.motionY;
entity.motionZ = owner.motionZ;
entity.prevRotationPitch = owner.prevRotationPitch;
entity.prevRotationYaw = owner.prevRotationYaw;
entity.distanceWalkedOnStepModified = owner.distanceWalkedOnStepModified;
entity.distanceWalkedModified = owner.distanceWalkedModified;
entity.prevDistanceWalkedModified = owner.prevDistanceWalkedModified;
if (entity instanceof EntityLivingBase) {
EntityLivingBase l = (EntityLivingBase)entity;
l.rotationYawHead = owner.rotationYawHead; l.rotationYawHead = owner.rotationYawHead;
l.prevRotationYawHead = owner.prevRotationYawHead; l.prevRotationYawHead = owner.prevRotationYawHead;
@ -145,32 +166,27 @@ public class SpellDisguise extends AbstractSpell {
l.setHealth(owner.getHealth()); l.setHealth(owner.getHealth());
for (EntityEquipmentSlot i : EntityEquipmentSlot.values()) { for (EntityEquipmentSlot i : EntityEquipmentSlot.values()) {
l.setItemStackToSlot(i, owner.getItemStackFromSlot(i)); ItemStack neu = owner.getItemStackFromSlot(i);
ItemStack old = l.getItemStackFromSlot(i);
if (old != neu) {
l.setItemStackToSlot(i, neu);
}
} }
} }
if (owner.world.isRemote) { if (entity instanceof EntityLiving) {
// entity.setPositionAndRotationDirect(owner.posX, owner.posY, owner.posZ, owner.rotationYaw, owner.rotationPitch, 1, false); EntityLiving l = (EntityLiving)entity;
l.setNoAI(true);
} }
entity.copyLocationAndAnglesFrom(owner); if (entity instanceof EntityPlayer) {
EntityPlayer l = (EntityPlayer)entity;
entity.setNoGravity(true); l.chasingPosX = l.posX;
l.chasingPosY = l.posY;
entity.prevPosX = owner.prevPosX; l.chasingPosZ = l.posZ;
entity.prevPosY = owner.prevPosY; }
entity.prevPosZ = owner.prevPosZ;
entity.motionX = owner.motionX;
entity.motionY = owner.motionY;
entity.motionZ = owner.motionZ;
entity.prevRotationPitch = owner.prevRotationPitch;
entity.prevRotationYaw = owner.prevRotationYaw;
entity.distanceWalkedOnStepModified = owner.distanceWalkedOnStepModified;
entity.distanceWalkedModified = owner.distanceWalkedModified;
entity.prevDistanceWalkedModified = owner.prevDistanceWalkedModified;
if (owner.isBurning()) { if (owner.isBurning()) {
entity.setFire(1); entity.setFire(1);
@ -195,6 +211,10 @@ public class SpellDisguise extends AbstractSpell {
player.eyeHeight = entity.getEyeHeight(); player.eyeHeight = entity.getEyeHeight();
if (entity instanceof IOwned) {
IOwned.cast(entity).setOwner(player.getGameProfile().getId());
}
if (UClient.instance().isClientPlayer(player)) { if (UClient.instance().isClientPlayer(player)) {
entity.setAlwaysRenderNameTag(false); entity.setAlwaysRenderNameTag(false);
entity.setCustomNameTag(""); entity.setCustomNameTag("");