diff --git a/src/main/java/com/minelittlepony/unicopia/UClient.java b/src/main/java/com/minelittlepony/unicopia/UClient.java index 38137afb..1a472359 100644 --- a/src/main/java/com/minelittlepony/unicopia/UClient.java +++ b/src/main/java/com/minelittlepony/unicopia/UClient.java @@ -56,6 +56,10 @@ public class UClient { return false; } + public int getViewMode() { + return 0; + } + public void preInit(FMLPreInitializationEvent event) {} public void init(FMLInitializationEvent event) {} diff --git a/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java index 58cf072d..04efb6e5 100644 --- a/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/UnicopiaClient.java @@ -22,6 +22,7 @@ import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @@ -100,6 +101,21 @@ public class UnicopiaClient extends UClient { return getPlayer().getGameProfile().getId().equals(player.getGameProfile().getId()); } + @Override + public int getViewMode() { + return Minecraft.getMinecraft().gameSettings.thirdPersonView; + } + + @SideOnly(Side.CLIENT) + @SubscribeEvent + public static void preEntityRender(RenderLivingEvent.Pre event) { + if (event.getEntity() instanceof EntityPlayer) { + if (PlayerSpeciesList.instance().getPlayer((EntityPlayer)event.getEntity()).isInvisible()) { + event.setCanceled(true); + } + } + } + @SideOnly(Side.CLIENT) @Override public void preInit(FMLPreInitializationEvent event) { diff --git a/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java b/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java index 57aafee2..6b4d5bdc 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java +++ b/src/main/java/com/minelittlepony/unicopia/network/EffectSync.java @@ -28,11 +28,18 @@ public class EffectSync { NBTTagCompound comp = owned.getEntity().getDataManager().get(param); if (comp == null || !comp.hasKey("effect_id")) { - effect = null; + if (effect != null) { + effect.setDead(); + effect = null; + } } else { String id = comp.getString("effect_id"); if (effect == null || !effect.getName().contentEquals(id)) { + if (effect != null) { + effect.setDead(); + effect = null; + } effect = SpellRegistry.instance().createEffectFromNBT(comp); } else if (owned.getEntity().world.isRemote) { effect.readFromNBT(comp); @@ -43,6 +50,9 @@ public class EffectSync { } public void set(IMagicEffect effect) { + if (this.effect != null && this.effect != effect) { + this.effect.setDead(); + } this.effect = effect; if (effect == null) { diff --git a/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java b/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java index 4eb7194f..604de51f 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java +++ b/src/main/java/com/minelittlepony/unicopia/player/IPlayer.java @@ -54,6 +54,10 @@ public interface IPlayer extends ICaster, IRaceContainer activeAbility = null; public PlayerAbilityDelegate(IPlayer player) { @@ -28,23 +29,21 @@ class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable power) { + public synchronized void tryUseAbility(IPower power) { if (canSwitchStates() || activeAbility != power) { - abilityTriggered = false; activeAbility = power; - warmup = 0; - cooldown = power.getCooldownTime(player); + warmup = power.getWarmupTime(player); + cooldown = 0; } } @Override - public void tryClearAbility() { - if (canSwitchStates() || activeAbility != null) { - abilityTriggered = false; + public synchronized void tryClearAbility() { + if (canSwitchStates()) { activeAbility = null; warmup = 0; cooldown = 0; @@ -57,34 +56,28 @@ class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable 0) { + warmup--; + activeAbility.preApply(player); + } else if (player.isClientPlayer()) { + if (activateAbility()) { + cooldown = activeAbility.getCooldownTime(player); + } else { + cooldown = 0; } - } else if (cooldown > 0) { - activeAbility.postApply(player); + } + + if (cooldown > 0 && activeAbility != null) { cooldown--; + activeAbility.postApply(player); } } } @Override public void writeToNBT(NBTTagCompound compound) { - compound.setBoolean("triggered", abilityTriggered); compound.setInteger("warmup", warmup); compound.setInteger("cooldown", cooldown); @@ -95,10 +88,9 @@ class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable { @@ -107,11 +99,15 @@ class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable extends IKeyBind { * @param w The player's world * @return Data to be sent, or null if activation failed */ + @Nullable T tryActivate(EntityPlayer player, World w); Class getPackageType(); diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerDisguise.java b/src/main/java/com/minelittlepony/unicopia/power/PowerDisguise.java new file mode 100644 index 00000000..0c589642 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerDisguise.java @@ -0,0 +1,68 @@ +package com.minelittlepony.unicopia.power; + +import javax.annotation.Nullable; + +import org.lwjgl.input.Keyboard; + +import com.minelittlepony.unicopia.UParticles; +import com.minelittlepony.unicopia.player.IPlayer; +import com.minelittlepony.unicopia.player.PlayerSpeciesList; +import com.minelittlepony.unicopia.power.data.Hit; +import com.minelittlepony.unicopia.spell.IMagicEffect; +import com.minelittlepony.unicopia.spell.SpellDisguise; +import com.minelittlepony.util.vector.VecHelper; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.SoundEvents; +import net.minecraft.util.SoundCategory; +import net.minecraft.world.World; + +public class PowerDisguise extends PowerFeed { + + @Override + public String getKeyName() { + return "unicopia.power.diguise"; + } + + @Override + public int getKeyCode() { + return Keyboard.KEY_P; + } + + @Nullable + @Override + public Hit tryActivate(EntityPlayer player, World w) { + return new Hit(); + } + + @Override + public void apply(EntityPlayer player, Hit data) { + Entity looked = VecHelper.getLookedAtEntity(player, 17); + + IPlayer iplayer = PlayerSpeciesList.instance().getPlayer(player); + + player.world.playSound(null, player.getPosition(), SoundEvents.E_PARROT_IM_POLAR_BEAR, SoundCategory.PLAYERS, 1.4F, 0.4F); + + IMagicEffect effect = iplayer.getEffect(); + if (effect instanceof SpellDisguise && !effect.getDead()) { + ((SpellDisguise)effect).setDisguise(looked); + } else if (looked != null) { + iplayer.setEffect(new SpellDisguise().setDisguise(looked)); + } + + iplayer.sendCapabilities(true); + } + + @Override + public void preApply(IPlayer player) { + player.addEnergy(2); + IPower.spawnParticles(UParticles.MAGIC_PARTICLE, player, 5); + } + + @Override + public void postApply(IPlayer player) { + player.setEnergy(0); + IPower.spawnParticles(UParticles.MAGIC_PARTICLE, player, 5); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerFeed.java b/src/main/java/com/minelittlepony/unicopia/power/PowerFeed.java index fb78d632..ddb39476 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowerFeed.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerFeed.java @@ -2,6 +2,8 @@ package com.minelittlepony.unicopia.power; import java.util.List; +import javax.annotation.Nullable; + import org.lwjgl.input.Keyboard; import com.minelittlepony.unicopia.Race; @@ -51,6 +53,7 @@ public class PowerFeed implements IPower { return playerSpecies == Race.CHANGELING; } + @Nullable @Override public Hit tryActivate(EntityPlayer player, World w) { if (player.getHealth() < player.getMaxHealth() || player.canEat(false)) { diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowersRegistry.java b/src/main/java/com/minelittlepony/unicopia/power/PowersRegistry.java index 2b2e1be5..620315f1 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowersRegistry.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowersRegistry.java @@ -31,6 +31,7 @@ public class PowersRegistry { registerPower(new PowerGrow()); registerPower(new PowerFeed()); registerPower(new PowerCarry()); + registerPower(new PowerDisguise()); } public boolean hasRegisteredPower(int keyCode) { diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java new file mode 100644 index 00000000..ac9f4be7 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java @@ -0,0 +1,227 @@ +package com.minelittlepony.unicopia.spell; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.UClient; +import com.minelittlepony.unicopia.player.IPlayer; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.nbt.NBTTagCompound; + +public class SpellDisguise extends AbstractSpell { + + @Nonnull + private String entityId = ""; + + @Nullable + private Entity entity; + + @Nullable + private NBTTagCompound entityNbt; + + @Override + public String getName() { + return "disguise"; + } + + @Override + public int getTint() { + return 0; + } + + public SpellDisguise setDisguise(@Nullable Entity entity) { + this.entityNbt = null; + + if (this.entity != null) { + this.entity.setDead(); + } + + this.entity = null; + + this.entityId = ""; + + if (entity != null) { + this.entityId = EntityList.getKey(entity).toString(); + this.entityNbt = entity.writeToNBT(new NBTTagCompound()); + this.entityNbt.setString("id", entityId); + } + + return this; + } + + @Override + public boolean update(ICaster source, int level) { + if (entity == null && entityNbt != null) { + entity = EntityList.createEntityFromNBT(entityNbt, source.getWorld()); + + if (entity != null && source.getWorld().isRemote) { + source.getWorld().spawnEntity(entity); + } + + entityNbt = null; + } + + EntityLivingBase owner = source.getOwner(); + + if (owner == null) { + return true; + } + + if (entity != null) { + if (entity instanceof EntityLiving) { + EntityLiving l = (EntityLiving)entity; + + l.setNoAI(true); + + l.rotationYawHead = owner.rotationYawHead; + l.prevRotationYawHead = owner.prevRotationYawHead; + l.renderYawOffset = owner.renderYawOffset; + l.prevRenderYawOffset = owner.prevRenderYawOffset; + + l.limbSwing = owner.limbSwing; + l.limbSwingAmount = owner.limbSwingAmount; + l.prevLimbSwingAmount = owner.prevLimbSwingAmount; + + l.swingingHand = owner.swingingHand; + l.swingProgress = owner.swingProgress; + l.swingProgressInt = owner.swingProgressInt; + l.isSwingInProgress = owner.isSwingInProgress; + + for (EntityEquipmentSlot i : EntityEquipmentSlot.values()) { + l.setItemStackToSlot(i, owner.getItemStackFromSlot(i)); + } + + if (l.world.rand.nextInt(1000) < l.livingSoundTime++) { + l.playLivingSound(); + l.livingSoundTime = -l.getTalkInterval(); + } + } + + + entity.copyLocationAndAnglesFrom(owner); + + 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; + + owner.height = entity.height; + + entity.setSneaking(owner.isSneaking()); + + entity.setInvisible(false); + + if (source instanceof IPlayer) { + ((IPlayer) source).setInvisible(true); + } + owner.setInvisible(true); + + if (owner instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer)owner; + + player.eyeHeight = entity.getEyeHeight(); + + if (UClient.instance().isClientPlayer(player)) { + entity.setAlwaysRenderNameTag(false); + entity.setCustomNameTag(""); + + if (UClient.instance().getViewMode() == 0) { + entity.setInvisible(true); + entity.posY = -10; + } + } else { + entity.setAlwaysRenderNameTag(true); + entity.setCustomNameTag(player.getName()); + } + } + + if (!(source instanceof IPlayer) || ((IPlayer) source).getPlayerSpecies() == Race.CHANGELING) { + return true; + } + } + + owner.setInvisible(false); + + if (source instanceof IPlayer) { + ((IPlayer) source).setInvisible(false); + } + + + return false; + } + + @Override + public void setDead() { + super.setDead(); + + if (entity != null) { + entity.setDead(); + entity = null; + } + } + + @Override + public void render(ICaster source, int level) { + + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + + compound.setString("entityId", entityId); + compound.setBoolean("dead", getDead()); + + if (entityNbt != null) { + compound.setTag("entity", entityNbt); + } else if (entity != null) { + NBTTagCompound entityTag = new NBTTagCompound(); + entity.writeToNBT(entityTag); + entityTag.setString("id", entityId); + + compound.setTag("entity", entityTag); + } + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + String newId = compound.getString("entityId"); + + if (!newId.contentEquals(entityId)) { + entityNbt = null; + + if (entity != null) { + entity.setDead(); + entity = null; + } + } + + if (compound.hasKey("entity")) { + entityId = newId; + + entityNbt = compound.getCompoundTag("entity"); + + if (entity != null) { + entity.readFromNBT(entityNbt); + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java index 80c0df2e..d5505850 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java @@ -32,6 +32,7 @@ public class SpellRegistry { registerSpell(SpellIce::new); registerSpell(SpellPortal::new); registerSpell(SpellVortex::new); + registerSpell(SpellDisguise::new); } public IMagicEffect getSpellFromName(String name) { diff --git a/src/main/java/com/minelittlepony/util/vector/VecHelper.java b/src/main/java/com/minelittlepony/util/vector/VecHelper.java index 40d1837a..21ad5e1e 100644 --- a/src/main/java/com/minelittlepony/util/vector/VecHelper.java +++ b/src/main/java/com/minelittlepony/util/vector/VecHelper.java @@ -38,6 +38,7 @@ public class VecHelper { /** * Gets the entity the player is currently looking at, or null. */ + @Nullable public static Entity getLookedAtEntity(EntityLivingBase e, int reach) { RayTraceResult objectMouseOver = getObjectMouseOver(e, reach, 1);