mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fix up spells slightly
This commit is contained in:
parent
c9e912a378
commit
38e7b8bc36
11 changed files with 200 additions and 169 deletions
|
@ -12,12 +12,12 @@ public final class Predicates {
|
||||||
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds();
|
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canInteractWithClouds();
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Predicate<EntityPlayer> MAGI = player -> {
|
public static final Predicate<Entity> MAGI = entity -> {
|
||||||
return player != null && PlayerSpeciesList.instance().getPlayer(player).getPlayerSpecies().canCast();
|
return entity instanceof EntityPlayer && PlayerSpeciesList.instance().getPlayer((EntityPlayer)entity).getPlayerSpecies().canCast();
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Predicate<Entity> ITEMS = entity -> {
|
public static final Predicate<Entity> ITEMS = entity -> {
|
||||||
return entity.isEntityAlive() && entity instanceof EntityItem;
|
return entity instanceof EntityItem && entity.isEntityAlive();
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Predicate<EntityItem> ITEM_INTERACT_WITH_CLOUDS = item -> {
|
public static final Predicate<EntityItem> ITEM_INTERACT_WITH_CLOUDS = item -> {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package com.minelittlepony.unicopia.entity;
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Predicates;
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
import com.minelittlepony.unicopia.UItems;
|
import com.minelittlepony.unicopia.UItems;
|
||||||
import com.minelittlepony.unicopia.item.ItemSpell;
|
import com.minelittlepony.unicopia.item.ICastable;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.spell.ICaster;
|
import com.minelittlepony.unicopia.spell.ICaster;
|
||||||
|
import com.minelittlepony.unicopia.spell.ILevelled;
|
||||||
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||||
|
|
||||||
|
@ -28,7 +31,7 @@ import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase> {
|
public class EntitySpell extends EntityLiving implements IMagicals, ICaster<EntityLivingBase>, ILevelled {
|
||||||
|
|
||||||
private EntityLivingBase owner = null;
|
private EntityLivingBase owner = null;
|
||||||
|
|
||||||
|
@ -102,7 +105,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setOwner(String ownerName) {
|
protected void setOwner(String ownerName) {
|
||||||
if (ownerName != null && ownerName.length() != 0) {
|
if (!StringUtils.isEmpty(ownerName)) {
|
||||||
dataManager.set(OWNER, ownerName);
|
dataManager.set(OWNER, ownerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,7 +113,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
protected String getOwnerName() {
|
protected String getOwnerName() {
|
||||||
String ownerName = dataManager.get(OWNER);
|
String ownerName = dataManager.get(OWNER);
|
||||||
|
|
||||||
if (ownerName == null || ownerName.length() == 0) {
|
if (!StringUtils.isEmpty(ownerName)) {
|
||||||
if (owner instanceof EntityPlayer) {
|
if (owner instanceof EntityPlayer) {
|
||||||
return owner.getName();
|
return owner.getName();
|
||||||
}
|
}
|
||||||
|
@ -135,7 +138,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
|
|
||||||
protected void displayTick() {
|
protected void displayTick() {
|
||||||
if (hasEffect()) {
|
if (hasEffect()) {
|
||||||
getEffect().renderAt(this, world, posX, posY, posZ, getLevel());
|
getEffect().render(this, getCurrentLevel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +155,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
setDead();
|
setDead();
|
||||||
onDeath();
|
onDeath();
|
||||||
} else {
|
} else {
|
||||||
getEffect().updateAt(this, world, posX, posY, posZ, getLevel());
|
getEffect().update(this, getCurrentLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getEffect().allowAI()) {
|
if (getEffect().allowAI()) {
|
||||||
|
@ -186,7 +189,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.NEUTRAL, sound.getVolume(), sound.getPitch(), true);
|
world.playSound(posX, posY, posZ, sound.getBreakSound(), SoundCategory.NEUTRAL, sound.getVolume(), sound.getPitch(), true);
|
||||||
|
|
||||||
if (world.getGameRules().getBoolean("doTileDrops")) {
|
if (world.getGameRules().getBoolean("doTileDrops")) {
|
||||||
int level = getLevel();
|
int level = getCurrentLevel();
|
||||||
|
|
||||||
ItemStack stack = new ItemStack(UItems.spell, level + 1);
|
ItemStack stack = new ItemStack(UItems.spell, level + 1);
|
||||||
if (hasEffect()) {
|
if (hasEffect()) {
|
||||||
|
@ -204,44 +207,14 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
super.setDead();
|
super.setDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLevel() {
|
|
||||||
return dataManager.get(LEVEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(int radius) {
|
|
||||||
dataManager.set(LEVEL, radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean tryLevelUp(ItemStack stack) {
|
|
||||||
|
|
||||||
if (SpellRegistry.stackHasEnchantment(stack)) {
|
|
||||||
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
increaseLevel();
|
|
||||||
|
|
||||||
if (!world.isRemote) {
|
|
||||||
if ((rand.nextFloat() * getLevel()) > 10 || overLevelCap()) {
|
|
||||||
world.createExplosion(this, posX, posY, posZ, getLevel()/2, true);
|
|
||||||
setDead();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
|
public EnumActionResult applyPlayerInteraction(EntityPlayer player, Vec3d vec, EnumHand hand) {
|
||||||
if (Predicates.MAGI.test(player)) {
|
if (Predicates.MAGI.test(player)) {
|
||||||
ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND);
|
ItemStack currentItem = player.getHeldItem(EnumHand.MAIN_HAND);
|
||||||
|
|
||||||
if (currentItem != null && currentItem.getItem() instanceof ItemSpell) {
|
if (currentItem != null
|
||||||
tryLevelUp(currentItem);
|
&& currentItem.getItem() instanceof ICastable
|
||||||
|
&& ((ICastable)currentItem.getItem()).canFeed(this, currentItem)
|
||||||
|
&& tryLevelUp(currentItem)) {
|
||||||
|
|
||||||
if (!player.capabilities.isCreativeMode) {
|
if (!player.capabilities.isCreativeMode) {
|
||||||
currentItem.shrink(1);
|
currentItem.shrink(1);
|
||||||
|
@ -258,24 +231,48 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
return EnumActionResult.FAIL;
|
return EnumActionResult.FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increaseLevel() {
|
public boolean tryLevelUp(ItemStack stack) {
|
||||||
setLevel(getLevel() + 1);
|
if (SpellRegistry.stackHasEnchantment(stack)) {
|
||||||
|
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLevels(1);
|
||||||
|
|
||||||
|
if (!world.isRemote) {
|
||||||
|
if ((rand.nextFloat() * getCurrentLevel()) > 10 || overLevelCap()) {
|
||||||
|
world.createExplosion(this, posX, posY, posZ, getCurrentLevel()/2, true);
|
||||||
|
setDead();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxLevel() {
|
||||||
|
return getEffect().getMaxLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canLevelUp() {
|
@Override
|
||||||
int max = getEffect().getMaxLevel();
|
public int getCurrentLevel() {
|
||||||
return max < 0 || getLevel() < max;
|
return dataManager.get(LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentLevel(int level) {
|
||||||
|
dataManager.set(LEVEL, Math.min(level, 0));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean overLevelCap() {
|
public boolean overLevelCap() {
|
||||||
int max = getEffect().getMaxLevel();
|
int max = getMaxLevel();
|
||||||
return max > 0 && getLevel() >= (max * 1.1);
|
return max > 0 && getCurrentLevel() >= (max * 1.1);
|
||||||
}
|
|
||||||
|
|
||||||
public void decreaseLevel() {
|
|
||||||
int level = getLevel() - 1;
|
|
||||||
if (level < 0) level = 0;
|
|
||||||
setLevel(level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -287,7 +284,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
public void readEntityFromNBT(NBTTagCompound compound) {
|
public void readEntityFromNBT(NBTTagCompound compound) {
|
||||||
super.readEntityFromNBT(compound);
|
super.readEntityFromNBT(compound);
|
||||||
setOwner(compound.getString("ownerName"));
|
setOwner(compound.getString("ownerName"));
|
||||||
setLevel(compound.getInteger("level"));
|
setCurrentLevel(compound.getInteger("level"));
|
||||||
|
|
||||||
if (compound.hasKey("effect")) {
|
if (compound.hasKey("effect")) {
|
||||||
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
setEffect(SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect")));
|
||||||
|
@ -299,7 +296,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
super.writeEntityToNBT(compound);
|
super.writeEntityToNBT(compound);
|
||||||
|
|
||||||
compound.setString("ownerName", getOwnerName());
|
compound.setString("ownerName", getOwnerName());
|
||||||
compound.setInteger("level", getLevel());
|
compound.setInteger("level", getCurrentLevel());
|
||||||
|
|
||||||
if (hasEffect()) {
|
if (hasEffect()) {
|
||||||
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect()));
|
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(getEffect()));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.item;
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.EntitySpell;
|
||||||
import com.minelittlepony.unicopia.spell.IDispenceable;
|
import com.minelittlepony.unicopia.spell.IDispenceable;
|
||||||
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||||
import com.minelittlepony.unicopia.spell.SpellCastResult;
|
import com.minelittlepony.unicopia.spell.SpellCastResult;
|
||||||
|
@ -16,4 +17,7 @@ public interface ICastable extends IMagicalItem {
|
||||||
SpellCastResult onDispenseSpell(IBlockSource source, ItemStack stack, IDispenceable effect);
|
SpellCastResult onDispenseSpell(IBlockSource source, ItemStack stack, IDispenceable effect);
|
||||||
|
|
||||||
SpellCastResult onCastSpell(EntityPlayer player, World world, BlockPos pos, ItemStack stack, IMagicEffect effect, EnumFacing side, float hitX, float hitY, float hitZ);
|
SpellCastResult onCastSpell(EntityPlayer player, World world, BlockPos pos, ItemStack stack, IMagicEffect effect, EnumFacing side, float hitX, float hitY, float hitZ);
|
||||||
|
|
||||||
|
boolean canFeed(EntitySpell spell, ItemStack stack);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,4 +180,12 @@ public class ItemSpell extends Item implements ICastable {
|
||||||
|
|
||||||
return spell;
|
return spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canFeed(EntitySpell entity, ItemStack stack) {
|
||||||
|
|
||||||
|
IMagicEffect effect = entity.getEffect();
|
||||||
|
|
||||||
|
return effect != null && effect.getName().equals(SpellRegistry.getKeyFromStack(stack));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,8 @@ public class ModelGem extends ModelBase {
|
||||||
GlStateManager.translate(0, floatOffset, 0);
|
GlStateManager.translate(0, floatOffset, 0);
|
||||||
|
|
||||||
floatOffset = (spell.ticksExisted + stutter) / 20;
|
floatOffset = (spell.ticksExisted + stutter) / 20;
|
||||||
if (spell.getLevel() > 0) {
|
if (spell.getCurrentLevel() > 0) {
|
||||||
floatOffset *= spell.getLevel() + 1;
|
floatOffset *= spell.getCurrentLevel() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
floatOffset += spell.hoverStart;
|
floatOffset += spell.hoverStart;
|
||||||
|
|
|
@ -139,10 +139,10 @@ class PlayerCapabilities implements IPlayer, ICaster<EntityPlayer> {
|
||||||
setEffect(null);
|
setEffect(null);
|
||||||
} else {
|
} else {
|
||||||
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
|
if (entity.getEntityWorld().isRemote) { // && entity.getEntityWorld().getWorldTime() % 10 == 0
|
||||||
getEffect().render(entity);
|
getEffect().render(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getEffect().update(entity)) {
|
if (!getEffect().update(this)) {
|
||||||
setEffect(null);
|
setEffect(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public abstract class AbstractSpell implements IMagicEffect {
|
public abstract class AbstractSpell implements IMagicEffect {
|
||||||
|
|
||||||
protected boolean isDead = false;
|
protected boolean isDead = false;
|
||||||
|
@ -16,14 +13,4 @@ public abstract class AbstractSpell implements IMagicEffect {
|
||||||
public boolean getDead() {
|
public boolean getDead() {
|
||||||
return isDead;
|
return isDead;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean update(Entity source) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import com.minelittlepony.unicopia.player.IOwned;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
|
public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
|
||||||
void setEffect(IMagicEffect effect);
|
void setEffect(IMagicEffect effect);
|
||||||
|
@ -20,4 +22,12 @@ public interface ICaster<E extends EntityLivingBase> extends IOwned<E> {
|
||||||
default Entity getEntity() {
|
default Entity getEntity() {
|
||||||
return getOwner();
|
return getOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default World getWorld() {
|
||||||
|
return getEntity().getEntityWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
default BlockPos getOrigin() {
|
||||||
|
return getEntity().getPosition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
public interface ILevelled {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum level this spell can reach or -1 for unlimited.
|
||||||
|
* <br>
|
||||||
|
* If a gem goes past this level it is more likely to explode.
|
||||||
|
*/
|
||||||
|
default int getMaxLevel() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean canLevelUp() {
|
||||||
|
int max = getMaxLevel();
|
||||||
|
return max < 0 || getCurrentLevel() < max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getCurrentLevel();
|
||||||
|
|
||||||
|
void setCurrentLevel(int level);
|
||||||
|
|
||||||
|
default void addLevels(int levels) {
|
||||||
|
setCurrentLevel(getCurrentLevel() + levels);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,24 +2,10 @@ package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.InbtSerialisable;
|
import com.minelittlepony.unicopia.InbtSerialisable;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Interface for a magic spells
|
||||||
* Interface for a magic spell
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface IMagicEffect extends InbtSerialisable {
|
public interface IMagicEffect extends InbtSerialisable, ILevelled {
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum level this spell can reach or -1 for unlimited.
|
|
||||||
* <br>
|
|
||||||
* If a gem goes past this level it is more likely to explode.
|
|
||||||
*/
|
|
||||||
default int getMaxLevel() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
@ -39,42 +25,34 @@ public interface IMagicEffect extends InbtSerialisable {
|
||||||
* @param source The entity we are currently attached to.
|
* @param source The entity we are currently attached to.
|
||||||
* @return true to keep alive
|
* @return true to keep alive
|
||||||
*/
|
*/
|
||||||
boolean update(Entity source);
|
boolean update(ICaster<?> caster);
|
||||||
|
|
||||||
/**
|
|
||||||
* Called every tick when attached to a player. Used to apply particle effects.
|
|
||||||
* Is only called on the client side.
|
|
||||||
*
|
|
||||||
* @param source The entity we are currently attached to.
|
|
||||||
*/
|
|
||||||
default void render(Entity source) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called every tick when attached to a gem.
|
* Called every tick when attached to a gem.
|
||||||
*
|
*
|
||||||
* @param source The entity we are attached to.
|
* @param source The entity we are currently attached to.
|
||||||
* @param w The world
|
* @param level Current active spell level
|
||||||
* @param x Entity position x
|
|
||||||
* @param y Entity position y
|
|
||||||
* @param z Entity position z
|
|
||||||
* @param level Current spell level
|
|
||||||
*/
|
*/
|
||||||
boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level);
|
boolean update(ICaster<?> source, int level);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called every tick when attached to a player. Used to apply particle effects.
|
||||||
|
* Is only called on the client side.
|
||||||
|
*
|
||||||
|
* @param source The entity we are currently attached to.
|
||||||
|
*/
|
||||||
|
default void render(ICaster<?> source) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called every tick when attached to an entity to produce particle effects.
|
* Called every tick when attached to an entity to produce particle effects.
|
||||||
* Is only called on the client side.
|
* Is only called on the client side.
|
||||||
*
|
*
|
||||||
* @param source The entity we are attached to.
|
* @param source The entity we are attached to.
|
||||||
* @param w The world
|
|
||||||
* @param x Entity position x
|
|
||||||
* @param y Entity position y
|
|
||||||
* @param z Entity position z
|
|
||||||
* @param level Current spell level
|
* @param level Current spell level
|
||||||
*/
|
*/
|
||||||
default void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) {
|
default void render(ICaster<?> source, int level) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.client.particle.Particles;
|
import com.minelittlepony.unicopia.client.particle.Particles;
|
||||||
|
@ -15,8 +18,8 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public class SpellShield extends AbstractSpell {
|
public class SpellShield extends AbstractSpell {
|
||||||
|
|
||||||
|
@ -26,12 +29,18 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpellShield(int type) {
|
public SpellShield(int type) {
|
||||||
setStrength(type);
|
setCurrentLevel(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStrength(int level) {
|
@Override
|
||||||
strength = level;
|
public int getCurrentLevel() {
|
||||||
}
|
return strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentLevel(int level) {
|
||||||
|
strength = level;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -44,21 +53,28 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Entity source) {
|
public void render(ICaster<?> source) {
|
||||||
spawnParticles(source.getEntityWorld(), source.posX, source.posY, source.posZ, 4 + (strength * 2));
|
spawnParticles(source, 4 + (strength * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderAt(ICaster<?> source, World w, double x, double y, double z, int level) {
|
@Override
|
||||||
if (w.rand.nextInt(4 + level * 4) == 0) {
|
public void render(ICaster<?> source, int level) {
|
||||||
spawnParticles(w, x, y, z, 4 + (level * 2));
|
if (source.getWorld().rand.nextInt(4 + level * 4) == 0) {
|
||||||
|
spawnParticles(source, 4 + (level * 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void spawnParticles(World w, double x, double y, double z, int strength) {
|
protected void spawnParticles(ICaster<?> source, int strength) {
|
||||||
IShape sphere = new Sphere(true, strength);
|
IShape sphere = new Sphere(true, strength);
|
||||||
|
|
||||||
|
Random rand = source.getWorld().rand;
|
||||||
|
|
||||||
|
int x = source.getOrigin().getX();
|
||||||
|
int y = source.getOrigin().getY();
|
||||||
|
int z = source.getOrigin().getZ();
|
||||||
|
|
||||||
for (int i = 0; i < strength * 6; i++) {
|
for (int i = 0; i < strength * 6; i++) {
|
||||||
Vec3d pos = sphere.computePoint(w.rand);
|
Vec3d pos = sphere.computePoint(rand);
|
||||||
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
|
Particles.instance().spawnParticle(Unicopia.MAGIC_PARTICLE, false,
|
||||||
pos.x + x, pos.y + y, pos.z + z,
|
pos.x + x, pos.y + y, pos.z + z,
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
|
@ -66,12 +82,12 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(Entity source) {
|
public boolean update(ICaster<?> source) {
|
||||||
applyEntities(null, source, source.getEntityWorld(), source.posX, source.posY, source.posZ, strength);
|
update(source, strength);
|
||||||
|
|
||||||
if (source.getEntityWorld().getWorldTime() % 50 == 0) {
|
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
|
||||||
double radius = 4 + (strength * 2);
|
double radius = 4 + (strength * 2);
|
||||||
if (!IPower.takeFromPlayer((EntityPlayer)source, radius/4)) {
|
if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) {
|
||||||
setDead();
|
setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,49 +96,52 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateAt(ICaster<?> source, World w, double x, double y, double z, int level) {
|
public boolean update(ICaster<?> source, int level) {
|
||||||
return applyEntities(source, source.getOwner(), w, x, y, z, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean applyEntities(ICaster<?> source, Entity owner, World w, double x, double y, double z, int level) {
|
|
||||||
double radius = 4 + (level * 2);
|
double radius = 4 + (level * 2);
|
||||||
|
|
||||||
AxisAlignedBB bb = new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius);
|
Entity owner = source.getOwner();
|
||||||
|
BlockPos pos = source.getOrigin();
|
||||||
|
|
||||||
for (Entity i : w.getEntitiesWithinAABBExcludingEntity(source == null ? null : source.getEntity(), bb)) {
|
int x = pos.getX(), y = pos.getY(), z = pos.getZ();
|
||||||
if ((!i.equals(owner)
|
|
||||||
|| (owner instanceof EntityPlayer
|
|
||||||
&& !PlayerSpeciesList.instance().getPlayer((EntityPlayer)owner).getPlayerSpecies().canCast()))) {
|
|
||||||
|
|
||||||
double dist = i.getDistance(x, y, z);
|
BlockPos begin = pos.add(-radius, -radius, -radius);
|
||||||
double dist2 = i.getDistance(x, y - i.getEyeHeight(), z);
|
BlockPos end = pos.add(radius, radius, radius);
|
||||||
|
|
||||||
boolean projectile = ProjectileUtil.isProjectile(i);
|
AxisAlignedBB bb = new AxisAlignedBB(begin, end);
|
||||||
|
|
||||||
if (dist <= radius || dist2 <= radius) {
|
boolean ownerIsValid = Predicates.MAGI.test(owner);
|
||||||
if (projectile) {
|
|
||||||
if (!ProjectileUtil.isProjectileThrownBy(i, owner)) {
|
|
||||||
if (dist < radius/2) {
|
|
||||||
i.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1f, 1);
|
|
||||||
i.setDead();
|
|
||||||
} else {
|
|
||||||
ricochet(i, x, y, z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (i instanceof EntityLivingBase) {
|
|
||||||
double force = dist;
|
|
||||||
if (i instanceof EntityPlayer) {
|
|
||||||
force = calculateForce((EntityPlayer)i);
|
|
||||||
}
|
|
||||||
|
|
||||||
i.addVelocity(
|
for (Entity i : source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, entity -> !(ownerIsValid && entity.equals(owner)))) {
|
||||||
-(x - i.posX) / force,
|
double dist = i.getDistance(x, y, z);
|
||||||
-(y - i.posY) / force + (dist < 1 ? dist : 0),
|
double dist2 = i.getDistance(x, y - i.getEyeHeight(), z);
|
||||||
-(z - i.posZ) / force);
|
|
||||||
}
|
if (dist > radius && dist2 > radius) {
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ProjectileUtil.isProjectile(i)) {
|
||||||
|
if (!ProjectileUtil.isProjectileThrownBy(i, owner)) {
|
||||||
|
if (dist < radius/2) {
|
||||||
|
i.playSound(SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, 0.1F, 1);
|
||||||
|
i.setDead();
|
||||||
|
} else {
|
||||||
|
ricochet(i, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (i instanceof EntityLivingBase) {
|
||||||
|
double force = Math.min(0.25F, dist);
|
||||||
|
|
||||||
|
if (i instanceof EntityPlayer) {
|
||||||
|
force = calculateForce((EntityPlayer)i);
|
||||||
|
}
|
||||||
|
|
||||||
|
i.addVelocity(
|
||||||
|
-(x - i.posX) / force,
|
||||||
|
-(y - i.posY) / force + (dist < 1 ? dist : 0),
|
||||||
|
-(z - i.posZ) / force);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,11 +161,11 @@ public class SpellShield extends AbstractSpell {
|
||||||
return force;
|
return force;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ricochet(Entity projectile, double x, double y, double z) {
|
private void ricochet(Entity projectile, BlockPos pos) {
|
||||||
Vec3d position = new Vec3d(projectile.posX, projectile.posY, projectile.posZ);
|
Vec3d position = new Vec3d(projectile.posX, projectile.posY, projectile.posZ);
|
||||||
Vec3d motion = new Vec3d(projectile.motionX, projectile.motionY, projectile.motionZ);
|
Vec3d motion = new Vec3d(projectile.motionX, projectile.motionY, projectile.motionZ);
|
||||||
|
|
||||||
Vec3d normal = position.subtract(x, y, z).normalize();
|
Vec3d normal = position.subtract(pos.getX(), pos.getY(), pos.getZ()).normalize();
|
||||||
Vec3d approach = motion.subtract(normal);
|
Vec3d approach = motion.subtract(normal);
|
||||||
|
|
||||||
if (approach.length() >= motion.length()) {
|
if (approach.length() >= motion.length()) {
|
||||||
|
@ -154,10 +173,12 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
compound.setInteger("spell_strength", strength);
|
compound.setInteger("spell_strength", strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
strength = compound.getInteger("spell_strength");
|
strength = compound.getInteger("spell_strength");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue