diff --git a/src/main/java/com/minelittlepony/unicopia/forgebullshit/FBS.java b/src/main/java/com/minelittlepony/unicopia/forgebullshit/FBS.java index 91b93aaf..dc90ed5a 100644 --- a/src/main/java/com/minelittlepony/unicopia/forgebullshit/FBS.java +++ b/src/main/java/com/minelittlepony/unicopia/forgebullshit/FBS.java @@ -1,8 +1,10 @@ package com.minelittlepony.unicopia.forgebullshit; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.entity.IMagicals; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; @@ -28,9 +30,11 @@ public class FBS { @SubscribeEvent public static void attach(AttachCapabilitiesEvent event) { - if (event.getObject() instanceof EntityPlayer - || event.getObject() instanceof EntityItem) { - event.addCapability(new ResourceLocation("unicopia", "race"), new Provider(event.getObject())); + Entity obj = event.getObject(); + + if ((obj instanceof EntityLivingBase && !(obj instanceof IMagicals)) + || obj instanceof EntityItem) { + event.addCapability(new ResourceLocation("unicopia", "race"), new Provider(obj)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemMagicStaff.java b/src/main/java/com/minelittlepony/unicopia/item/ItemMagicStaff.java index 8919f32e..3d6650a2 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ItemMagicStaff.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemMagicStaff.java @@ -6,7 +6,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import com.minelittlepony.unicopia.Predicates; -import com.minelittlepony.unicopia.power.IPower; +import com.minelittlepony.unicopia.player.IPlayer; +import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.spell.CasterUtils; import com.minelittlepony.unicopia.spell.IAligned; import com.minelittlepony.unicopia.spell.ICaster; @@ -82,12 +83,10 @@ public class ItemMagicStaff extends ItemStaff implements IAligned, ITossableItem if (attacker.isSneaking()) { stack.damageItem(50, attacker); - if (attacker instanceof EntityPlayer) { - IPower.takeFromPlayer((EntityPlayer)attacker, 4); - } + CasterUtils.toCaster(attacker).ifPresent(c -> c.subtractEnergyCost(4)); onImpact( - CasterUtils.toCaster(target).orElseGet(() -> CasterUtils.near(target)), + CasterUtils.near(target), target.getPosition(), target.getEntityWorld().getBlockState(target.getPosition()) ); @@ -140,9 +139,10 @@ public class ItemMagicStaff extends ItemStaff implements IAligned, ITossableItem @Override public void toss(World world, ItemStack stack, EntityPlayer player) { - CasterUtils.toCaster(player).ifPresent(effect::toss); + IPlayer iplayer = PlayerSpeciesList.instance().getPlayer(player); - IPower.takeFromPlayer(player, 4); + iplayer.subtractEnergyCost(4); + effect.toss(iplayer); stack.damageItem(1, player); } diff --git a/src/main/java/com/minelittlepony/unicopia/player/EntityCapabilities.java b/src/main/java/com/minelittlepony/unicopia/player/EntityCapabilities.java new file mode 100644 index 00000000..61a0fbba --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/player/EntityCapabilities.java @@ -0,0 +1,135 @@ +package com.minelittlepony.unicopia.player; + +import java.util.Map; + +import com.google.common.collect.Maps; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.network.EffectSync; +import com.minelittlepony.unicopia.spell.IAligned; +import com.minelittlepony.unicopia.spell.IAttachedEffect; +import com.minelittlepony.unicopia.spell.ICaster; +import com.minelittlepony.unicopia.spell.IMagicEffect; +import com.minelittlepony.unicopia.spell.SpellAffinity; +import com.minelittlepony.unicopia.spell.SpellRegistry; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.DataSerializers; +import net.minecraft.network.datasync.EntityDataManager; + +public class EntityCapabilities implements IRaceContainer, ICaster { + + private static final Map, DataParameter> EFFECT_KEYS = Maps.newHashMap(); + + private final DataParameter EFFECT; + + private final EffectSync effectDelegate; + + private EntityLivingBase entity; + + EntityCapabilities(EntityLivingBase entity) { + setOwner(entity); + + EFFECT = EFFECT_KEYS.computeIfAbsent(entity.getClass(), c -> { + return EntityDataManager.createKey(c, DataSerializers.COMPOUND_TAG); + }); + effectDelegate = new EffectSync<>(this, EFFECT); + + entity.getDataManager().register(EFFECT, new NBTTagCompound()); + } + + @Override + public Race getPlayerSpecies() { + return Race.HUMAN; + } + + @Override + public void setPlayerSpecies(Race race) { + } + + @Override + public void setEffect(IMagicEffect effect) { + effectDelegate.set(effect); + } + + @Override + public T getEffect(Class type, boolean update) { + return effectDelegate.get(type, update); + } + + @Override + public boolean hasEffect() { + return effectDelegate.has(); + } + + @Override + public void beforeUpdate() { + + } + + @Override + public void onUpdate() { + if (hasEffect()) { + IAttachedEffect effect = getEffect(IAttachedEffect.class, true); + + if (effect != null) { + if (entity.getEntityWorld().isRemote) { + effect.renderOnPerson(this); + } + + if (!effect.updateOnPerson(this)) { + setEffect(null); + } + } + } + } + + @Override + public void onDimensionalTravel(int destinationDimension) { + + } + + @Override + public void setOwner(EntityLivingBase owner) { + entity = owner; + } + + @Override + public EntityLivingBase getOwner() { + return entity; + } + + @Override + public int getCurrentLevel() { + return 0; + } + + @Override + public void setCurrentLevel(int level) { + } + + @Override + public SpellAffinity getAffinity() { + if (getOwner() instanceof IAligned) { + return ((IAligned)getOwner()).getAffinity(); + } + return SpellAffinity.NEUTRAL; + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + IMagicEffect effect = getEffect(); + + if (effect != null) { + compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(effect)); + } + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + if (compound.hasKey("effect")) { + setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"))); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/player/Hooks.java b/src/main/java/com/minelittlepony/unicopia/player/Hooks.java index 2f2d3003..36177f69 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/Hooks.java +++ b/src/main/java/com/minelittlepony/unicopia/player/Hooks.java @@ -9,7 +9,7 @@ import net.minecraft.util.math.RayTraceResult; import net.minecraftforge.event.entity.ProjectileImpactEvent; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent; -import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent; +import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.player.PlayerDropsEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent; @@ -31,7 +31,12 @@ class Hooks { } @SubscribeEvent - public static void onPlayerJump(LivingJumpEvent event) { + public static void onLivingUpdate(LivingEvent.LivingUpdateEvent event) { + PlayerSpeciesList.instance().getEntity(event.getEntityLiving()).onUpdate(); + } + + @SubscribeEvent + public static void onPlayerJump(LivingEvent.LivingJumpEvent event) { if (event.getEntityLiving() instanceof EntityPlayer) { if (PlayerSpeciesList.instance().getPlayer((EntityPlayer)event.getEntityLiving()).getGravity().getGravitationConstant() < 0) { event.getEntityLiving().motionY = -event.getEntityLiving().motionY; diff --git a/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java b/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java index e1920d82..0798d947 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java +++ b/src/main/java/com/minelittlepony/unicopia/player/PlayerCapabilities.java @@ -37,6 +37,7 @@ import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.network.play.server.SPacketSetPassengers; import net.minecraft.potion.PotionEffect; import net.minecraft.stats.StatList; +import net.minecraft.util.DamageSource; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; @@ -310,6 +311,22 @@ class PlayerCapabilities implements IPlayer { return true; } + @Override + public boolean subtractEnergyCost(double foodSubtract) { + if (!entity.capabilities.isCreativeMode) { + int food = (int)(entity.getFoodStats().getFoodLevel() - foodSubtract); + + if (food < 0) { + entity.getFoodStats().addStats(-entity.getFoodStats().getFoodLevel(), 0); + entity.attackEntityFrom(DamageSource.MAGIC, -food/2); + } else { + entity.getFoodStats().addStats((int)-foodSubtract, 0); + } + } + + return entity.getHealth() > 0; + } + @Override public boolean stepOnCloud() { EntityPlayer player = getOwner(); diff --git a/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java b/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java index 1cad4e1b..4d05be23 100644 --- a/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java +++ b/src/main/java/com/minelittlepony/unicopia/player/PlayerSpeciesList.java @@ -7,8 +7,10 @@ import javax.annotation.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.UConfig; import com.minelittlepony.unicopia.forgebullshit.FBS; +import com.minelittlepony.unicopia.spell.ICaster; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; @@ -65,6 +67,10 @@ public class PlayerSpeciesList { return new ItemCapabilities(); } + if (entity instanceof EntityLivingBase) { + return new EntityCapabilities((EntityLivingBase)entity); + } + throw new IllegalArgumentException("entity"); } @@ -82,6 +88,12 @@ public class PlayerSpeciesList { return getPlayer(IPlayer.getPlayerFromServer(playerId)); } + @SuppressWarnings("unchecked") + @Nullable + public ICaster getCaster(T entity) { + return (ICaster)getEntity(entity); + } + public IRaceContainer getEntity(T entity) { return FBS.of(entity).getRaceContainer(); } diff --git a/src/main/java/com/minelittlepony/unicopia/power/IPower.java b/src/main/java/com/minelittlepony/unicopia/power/IPower.java index bd7f20d5..44e5fbe8 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/IPower.java +++ b/src/main/java/com/minelittlepony/unicopia/power/IPower.java @@ -10,38 +10,11 @@ import com.minelittlepony.util.shape.IShape; import com.minelittlepony.util.shape.Sphere; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.DamageSource; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public interface IPower extends IKeyBind { - /** - * Subtracts a given food amount from the player. - * Harms the player if there is not enough hunger available. - */ - static boolean takeFromPlayer(EntityPlayer player, double foodSubtract) { - if (!player.capabilities.isCreativeMode) { - int food = (int)(player.getFoodStats().getFoodLevel() - foodSubtract); - if (food < 0) { - player.getFoodStats().addStats(-player.getFoodStats().getFoodLevel(), 0); - player.attackEntityFrom(DamageSource.MAGIC, -food/2); - } else { - player.getFoodStats().addStats((int)-foodSubtract, 0); - } - } - - return player.getHealth() > 0; - } - - static double getPlayerEyeYPos(EntityPlayer player) { - if (player.getEntityWorld().isRemote) { - return player.posY + player.getEyeHeight() - player.getYOffset(); - } - return player.posY + player.getEyeHeight() - 1; - } - static void spawnParticles(int particleId, Entity entity, int count, int...args) { double halfDist = entity.getEyeHeight() / 1.5; double middle = entity.getEntityBoundingBox().minY + halfDist; diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerGrow.java b/src/main/java/com/minelittlepony/unicopia/power/PowerGrow.java index ce94b664..c8b5dc88 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowerGrow.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerGrow.java @@ -74,7 +74,7 @@ public class PowerGrow implements IPower { } if (count > 0) { - IPower.takeFromPlayer(player.getOwner(), count * 5); + player.subtractEnergyCost(count * 5); } } diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java b/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java index a7dd718c..0012873a 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java @@ -166,13 +166,13 @@ public class PowerStomp implements IPower { spawnParticleRing(player, i); } - IPower.takeFromPlayer(player, rad); + iplayer.subtractEnergyCost(rad); } else if (data.hitType == 1) { boolean harmed = player.getHealth() < player.getMaxHealth(); if (harmed && player.world.rand.nextInt(30) == 0) { - IPower.takeFromPlayer(player, 3); + iplayer.subtractEnergyCost(3); return; } @@ -182,12 +182,12 @@ public class PowerStomp implements IPower { UWorld.enqueueTask(w -> removeTree(w, data.pos())); } - IPower.takeFromPlayer(player, 3); + iplayer.subtractEnergyCost(3); } else { int cost = dropApples(player.world, data.pos()); if (cost > 0) { - IPower.takeFromPlayer(player, cost * 3); + iplayer.subtractEnergyCost(cost * 3); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerTeleport.java b/src/main/java/com/minelittlepony/unicopia/power/PowerTeleport.java index 601308fd..153d10df 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowerTeleport.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerTeleport.java @@ -128,7 +128,7 @@ public class PowerTeleport implements IPower { } player.setPositionAndUpdate(data.x + (player.posX - Math.floor(player.posX)), data.y, data.z + (player.posZ - Math.floor(player.posZ))); - IPower.takeFromPlayer(player, distance); + iplayer.subtractEnergyCost(distance); player.fallDistance /= distance; diff --git a/src/main/java/com/minelittlepony/unicopia/spell/CasterUtils.java b/src/main/java/com/minelittlepony/unicopia/spell/CasterUtils.java index a56c0f34..a0582903 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/CasterUtils.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/CasterUtils.java @@ -9,6 +9,7 @@ import javax.annotation.Nullable; import com.google.common.collect.Streams; import com.minelittlepony.unicopia.Predicates; import com.minelittlepony.unicopia.entity.EntitySpell; +import com.minelittlepony.unicopia.entity.IMagicals; import com.minelittlepony.unicopia.player.PlayerSpeciesList; import net.minecraft.entity.Entity; @@ -19,6 +20,9 @@ import net.minecraft.util.math.BlockPos; public class CasterUtils { + /** + * Finds all surrounding spells withing range from the given caster. + */ public static Stream> findAllSpellsInRange(ICaster source, double radius) { BlockPos origin = source.getOrigin(); @@ -41,6 +45,9 @@ public class CasterUtils { .map(Optional::get); } + /** + * Finds all magically capabable entities in the world. + */ static Stream> findAllSpells(ICaster source) { return source.getWorld().getEntities(EntityLivingBase.class, e -> { return e instanceof ICaster || e instanceof EntityPlayer; @@ -67,29 +74,50 @@ public class CasterUtils { .filter(e -> !e.getDead()); } + /** + * Determines if the passed in entity is holding the named effect. + * By holding that meant the effect must be attached to the caster associated with the entity. + */ public static boolean isHoldingEffect(String effectName, Entity entity) { return Streams.stream(entity.getEquipmentAndArmor()) .map(SpellRegistry::getKeyFromStack) .anyMatch(s -> s.equals(effectName)); } + /** + * Creates a new caster at the position of the given entity. + * First attempts to convert the passed entity into a caster. + */ + @Nonnull public static ICaster near(@Nonnull Entity entity) { + ICaster result = toCasterRaw(entity); + + if (result != null) { + return result; + } + EntitySpell caster = new EntitySpell(entity.world); caster.copyLocationAndAnglesFrom(entity); return caster; } + /** + * Attempts to convert the passed entity into a caster using all the known methods. + */ public static Optional> toCaster(@Nullable Entity entity) { + return Optional.ofNullable(toCasterRaw(entity)); + } + private static ICaster toCasterRaw(Entity entity) { if (entity instanceof ICaster) { - return Optional.of((ICaster)entity); + return (ICaster)entity; } - if (entity instanceof EntityPlayer) { - return Optional.of(PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity)); + if (entity instanceof EntityLivingBase && !(entity instanceof IMagicals)) { + return PlayerSpeciesList.instance().getCaster((EntityLivingBase)entity); } - return Optional.empty(); + return null; } } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/IAttachedEffect.java b/src/main/java/com/minelittlepony/unicopia/spell/IAttachedEffect.java index a30b9741..1af01866 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/IAttachedEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/IAttachedEffect.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia.spell; -import com.minelittlepony.unicopia.player.IPlayer; - public interface IAttachedEffect extends IMagicEffect { /** * Called every tick when attached to a player. @@ -9,7 +7,7 @@ public interface IAttachedEffect extends IMagicEffect { * @param source The entity we are currently attached to. * @return true to keep alive */ - boolean updateOnPerson(IPlayer caster); + boolean updateOnPerson(ICaster caster); /** * Called every tick when attached to a player. Used to apply particle effects. @@ -17,5 +15,5 @@ public interface IAttachedEffect extends IMagicEffect { * * @param source The entity we are currently attached to. */ - default void renderOnPerson(IPlayer source) {} + default void renderOnPerson(ICaster source) {} } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java b/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java index e662b93a..86e62505 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java @@ -8,6 +8,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import com.minelittlepony.unicopia.entity.EntitySpell; +import com.minelittlepony.unicopia.entity.IMagicals; import com.minelittlepony.unicopia.player.IOwned; import com.minelittlepony.unicopia.power.IPower; import com.minelittlepony.util.shape.IShape; @@ -15,28 +16,45 @@ import com.minelittlepony.util.vector.VecHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.DamageSource; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public interface ICaster extends IOwned, ILevelled, IAligned { +/** + * Interface for any magically capable entities that can cast and persist spells. + */ +public interface ICaster extends IOwned, ILevelled, IAligned, IMagicals { void setEffect(@Nullable IMagicEffect effect); + /** + * Gets the active effect for this caster. + */ @Nullable default IMagicEffect getEffect(boolean update) { return getEffect(null, update); } + /** + * Gets the active effect for the matching given type. + * Returns null if no such effect exists for this caster. + */ @Nullable T getEffect(@Nullable Class type, boolean update); + /** + * Gets the active effect for this caster updating it if needed. + */ @Nullable default IMagicEffect getEffect() { return getEffect(true); } + /** + * Returns true if this caster has an active effect attached to it. + */ boolean hasEffect(); /** @@ -81,6 +99,17 @@ public interface ICaster extends IOwned, ILevelle return getEntity().getPosition(); } + /** + * Gets the center position where this caster is located. + */ + default Vec3d getOriginVector() { + return getEntity().getPositionVector(); + } + + /** + * Returns a new caster at the given position. + * This one is not altered, rather the method will return an entirely new caster with the same owner as this one. + */ default ICaster at(BlockPos newOrigin) { EntitySpell spell = new EntitySpell(getWorld()); spell.setPosition(newOrigin.getX(), newOrigin.getY(), newOrigin.getZ()); @@ -89,10 +118,6 @@ public interface ICaster extends IOwned, ILevelle return spell; } - default Vec3d getOriginVector() { - return getEntity().getPositionVector(); - } - default void spawnParticles(int particleId, int count, int...args) { IPower.spawnParticles(particleId, getEntity(), count, args); } @@ -107,6 +132,12 @@ public interface ICaster extends IOwned, ILevelle } } + default boolean subtractEnergyCost(double amount) { + getOwner().attackEntityFrom(DamageSource.MAGIC, (int)amount/2); + + return getOwner().getHealth() > 0; + } + default Stream> findAllSpells() { return CasterUtils.findAllSpells(this); } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/IDispenceable.java b/src/main/java/com/minelittlepony/unicopia/spell/IDispenceable.java index af0b5f42..8b6fdf8f 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/IDispenceable.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/IDispenceable.java @@ -6,7 +6,6 @@ import net.minecraft.util.EnumFacing; /** * Represents an object with an action to perform when dispensed from a dispenser. - * */ public interface IDispenceable extends IMagicEffect { diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellChangelingTrap.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellChangelingTrap.java index 45f447d5..860b9cfb 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellChangelingTrap.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellChangelingTrap.java @@ -1,12 +1,13 @@ package com.minelittlepony.unicopia.spell; +import com.minelittlepony.unicopia.entity.IMagicals; import com.minelittlepony.unicopia.init.UBlocks; import com.minelittlepony.unicopia.init.USounds; -import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.util.WorldEvent; import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -51,9 +52,14 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, return new ItemStack(Items.SLIME_BALL); } + private boolean checkStruggleCondition(ICaster caster) { + return !caster.getOrigin().equals(previousTrappedPosition) + || (!(caster.getOwner() instanceof EntityPlayer) && caster.getWorld().rand.nextInt(20) == 0); + } + @Override - public boolean updateOnPerson(IPlayer caster) { - EntityPlayer entity = caster.getOwner(); + public boolean updateOnPerson(ICaster caster) { + EntityLivingBase entity = caster.getOwner(); if (entity.motionY > 0) { entity.playSound(SoundEvents.BLOCK_SLIME_HIT, 1, 1); @@ -67,14 +73,12 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, setDirty(true); } - if (!caster.getWorld().isRemote) { - if (!origin.equals(previousTrappedPosition)) { - previousTrappedPosition = origin; - struggleCounter--; - WorldEvent.DESTROY_BLOCK.play(caster.getWorld(), origin, Blocks.SLIME_BLOCK.getDefaultState()); + if (!caster.getWorld().isRemote && checkStruggleCondition(caster)) { + previousTrappedPosition = origin; + struggleCounter--; + WorldEvent.DESTROY_BLOCK.play(caster.getWorld(), origin, Blocks.SLIME_BLOCK.getDefaultState()); - setDirty(true); - } + setDirty(true); } if (caster.getWorld().isAirBlock(origin) || caster.getWorld().getBlockState(origin).getBlock().isReplaceable(caster.getWorld(), origin)) { @@ -97,7 +101,10 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, entity.hurtTime = 2; entity.collidedHorizontally = true; entity.collided = true; - entity.capabilities.isFlying = false; + + if (entity instanceof EntityPlayer) { + ((EntityPlayer)entity).capabilities.isFlying = false; + } PotionEffect SLIME_REGEN = new PotionEffect(MobEffects.REGENERATION, 0); @@ -126,7 +133,7 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, } @Override - public void renderOnPerson(IPlayer source) { + public void renderOnPerson(ICaster source) { render(source); } @@ -140,7 +147,7 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, setDirty(true); } - protected void entrap(IPlayer e) { + protected void entrap(ICaster e) { SpellChangelingTrap existing = e.getEffect(SpellChangelingTrap.class, true); @@ -155,8 +162,8 @@ public class SpellChangelingTrap extends AbstractSpell implements ITossedEffect, public void onImpact(ICaster caster, BlockPos pos, IBlockState state) { if (caster.isLocal()) { caster.findAllEntitiesInRange(5) - .filter(e -> e instanceof EntityPlayer) - .map(e -> PlayerSpeciesList.instance().getPlayer((EntityPlayer)e)) + .filter(e -> !(e instanceof IMagicals) && e instanceof EntityLivingBase) + .map(e -> PlayerSpeciesList.instance().getCaster((EntityLivingBase)e)) .forEach(this::entrap); } } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java index 19149883..bc0379a1 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java @@ -146,8 +146,6 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu entity.setUniqueId(UUID.randomUUID()); entity.extinguish(); - PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).setEffect(null); - onEntityLoaded(source); } @@ -179,6 +177,8 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu return; } + CasterUtils.toCaster(entity).ifPresent(c -> c.setEffect(null)); + if (source.getWorld().isRemote) { source.getWorld().spawnEntity(entity); } @@ -289,7 +289,7 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu } @Override - public boolean updateOnPerson(IPlayer caster) { + public boolean updateOnPerson(ICaster caster) { return update(caster); } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java index 1866af4d..862be4b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellShield.java @@ -9,7 +9,6 @@ import com.minelittlepony.unicopia.particle.ParticleConnection; import com.minelittlepony.unicopia.particle.Particles; import com.minelittlepony.unicopia.player.IPlayer; import com.minelittlepony.unicopia.player.PlayerSpeciesList; -import com.minelittlepony.unicopia.power.IPower; import com.minelittlepony.util.ProjectileUtil; import com.minelittlepony.util.shape.Sphere; @@ -39,7 +38,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac } @Override - public void renderOnPerson(IPlayer source) { + public void renderOnPerson(ICaster source) { render(source); } @@ -57,7 +56,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac } @Override - public boolean updateOnPerson(IPlayer source) { + public boolean updateOnPerson(ICaster source) { int costMultiplier = applyEntities(source); if (costMultiplier > 0) { if (source.getOwner().ticksExisted % 20 == 0) { @@ -66,7 +65,7 @@ public class SpellShield extends AbstractSpell.RangedAreaSpell implements IAttac cost *= costMultiplier / 5F; System.out.println("Taking " + cost); - if (!IPower.takeFromPlayer(source.getOwner(), cost)) { + if (!source.subtractEnergyCost(cost)) { setDead(); } }