mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Fixed spell levels not being saved, fixed shields, fixed the drake gem
This commit is contained in:
parent
765d647018
commit
4e59f141b6
15 changed files with 254 additions and 121 deletions
|
@ -1,5 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.entity;
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Predicates;
|
import com.minelittlepony.unicopia.Predicates;
|
||||||
|
@ -79,12 +81,15 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEffect(IMagicEffect effect) {
|
public void setEffect(@Nullable IMagicEffect effect) {
|
||||||
effectDelegate.set(effect);
|
effectDelegate.set(effect);
|
||||||
|
|
||||||
effect.onPlaced(this);
|
if (effect != null) {
|
||||||
|
effect.onPlaced(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IMagicEffect getEffect() {
|
public IMagicEffect getEffect() {
|
||||||
return effectDelegate.get();
|
return effectDelegate.get();
|
||||||
|
@ -174,7 +179,7 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
displayTick();
|
displayTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getEffect() == null) {
|
if (!hasEffect()) {
|
||||||
setDead();
|
setDead();
|
||||||
} else {
|
} else {
|
||||||
if (getEffect().getDead()) {
|
if (getEffect().getDead()) {
|
||||||
|
@ -274,8 +279,8 @@ public class EntitySpell extends EntityLiving implements IMagicals, ICaster<Enti
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryLevelUp(ItemStack stack) {
|
public boolean tryLevelUp(ItemStack stack) {
|
||||||
if (SpellRegistry.stackHasEnchantment(stack)) {
|
if (hasEffect() && SpellRegistry.stackHasEnchantment(stack)) {
|
||||||
if (!getEffect().getName().equals(SpellRegistry.getKeyFromStack(stack))) {
|
if (!getEffect().getName().contentEquals(SpellRegistry.getKeyFromStack(stack))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,48 +1,142 @@
|
||||||
package com.minelittlepony.unicopia.entity.ai;
|
package com.minelittlepony.unicopia.entity.ai;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner;
|
|
||||||
import com.minelittlepony.unicopia.spell.ICaster;
|
import com.minelittlepony.unicopia.spell.ICaster;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.block.state.BlockFaceShape;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.ai.EntityAIFollow;
|
import net.minecraft.entity.ai.EntityAIBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.pathfinding.PathNavigate;
|
||||||
|
import net.minecraft.pathfinding.PathNavigateFlying;
|
||||||
|
import net.minecraft.pathfinding.PathNavigateGround;
|
||||||
|
import net.minecraft.pathfinding.PathNodeType;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntityAIFollowCaster extends EntityAIFollow {
|
public class EntityAIFollowCaster<T extends EntityLivingBase> extends EntityAIBase {
|
||||||
|
|
||||||
protected final ICaster<?> entity;
|
protected final ICaster<?> casted;
|
||||||
|
|
||||||
private static Field __followPredicate;
|
protected final EntityLiving entity;
|
||||||
|
|
||||||
static {
|
protected EntityLivingBase owner;
|
||||||
try {
|
|
||||||
Field f = EntityAIFollow.class.getDeclaredFields()[1];
|
protected final World world;
|
||||||
f.setAccessible(true);
|
|
||||||
__followPredicate = RegistryLockSpinner.makeNonFinal(f);
|
public final double followSpeed;
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
private final PathNavigate petPathfinder;
|
||||||
__followPredicate = null;
|
|
||||||
|
private int timeout;
|
||||||
|
|
||||||
|
public float maxDist;
|
||||||
|
public float minDist;
|
||||||
|
|
||||||
|
private float oldWaterCost;
|
||||||
|
|
||||||
|
public EntityAIFollowCaster(ICaster<T> casted, double followSpeed, float minDist, float maxDist) {
|
||||||
|
this.casted = casted;
|
||||||
|
|
||||||
|
this.entity = (EntityLiving)casted.getEntity();
|
||||||
|
this.world = casted.getWorld();
|
||||||
|
|
||||||
|
this.followSpeed = followSpeed;
|
||||||
|
this.petPathfinder = entity.getNavigator();
|
||||||
|
this.minDist = minDist;
|
||||||
|
this.maxDist = maxDist;
|
||||||
|
this.setMutexBits(3);
|
||||||
|
|
||||||
|
if (!(petPathfinder instanceof PathNavigateGround || petPathfinder instanceof PathNavigateFlying)) {
|
||||||
|
throw new IllegalArgumentException("Unsupported mob type for FollowOwnerGoal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityAIFollowCaster(ICaster<?> caster, double walkSpeed, float maxDistance, float area) {
|
/**
|
||||||
super((EntityLiving)caster.getEntity(), walkSpeed, maxDistance, area);
|
* Returns whether the EntityAIBase should begin execution.
|
||||||
|
*/
|
||||||
|
public boolean shouldExecute() {
|
||||||
|
EntityLivingBase owner = casted.getOwner();
|
||||||
|
|
||||||
entity = caster;
|
if (owner == null
|
||||||
|
|| (owner instanceof EntityPlayer && ((EntityPlayer)owner).isSpectator())
|
||||||
|
|| entity.getDistanceSq(owner) < (minDist * minDist)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (__followPredicate != null) {
|
this.owner = owner;
|
||||||
try {
|
|
||||||
__followPredicate.set(this, (Predicate<EntityLivingBase>)(e -> {
|
return true;
|
||||||
Entity owner = caster.getOwner();
|
}
|
||||||
return e != null && (e == owner || (owner != null && owner.getUniqueID().equals(e.getUniqueID())));
|
|
||||||
}));
|
@Override
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
public boolean shouldContinueExecuting() {
|
||||||
e.printStackTrace();
|
return !petPathfinder.noPath()
|
||||||
|
&& entity.getDistanceSq(owner) > (maxDist * maxDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startExecuting() {
|
||||||
|
timeout = 0;
|
||||||
|
oldWaterCost = entity.getPathPriority(PathNodeType.WATER);
|
||||||
|
entity.setPathPriority(PathNodeType.WATER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetTask() {
|
||||||
|
owner = null;
|
||||||
|
petPathfinder.clearPath();
|
||||||
|
entity.setPathPriority(PathNodeType.WATER, oldWaterCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateTask() {
|
||||||
|
entity.getLookHelper().setLookPositionWithEntity(owner, 10, entity.getVerticalFaceSpeed());
|
||||||
|
|
||||||
|
if (--timeout > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = 10;
|
||||||
|
|
||||||
|
if (petPathfinder.tryMoveToEntityLiving(owner, followSpeed)
|
||||||
|
|| entity.getLeashed()
|
||||||
|
|| entity.isRiding()
|
||||||
|
|| entity.getDistanceSq(owner) < 144) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = MathHelper.floor(owner.posX) - 2;
|
||||||
|
int y = MathHelper.floor(owner.getEntityBoundingBox().minY);
|
||||||
|
int z = MathHelper.floor(owner.posZ) - 2;
|
||||||
|
|
||||||
|
for (int offX = 0; offX <= 4; offX++) {
|
||||||
|
for (int offZ = 0; offZ <= 4; offZ++) {
|
||||||
|
if (canTeleport(x, y, z, offX, offZ)) {
|
||||||
|
|
||||||
|
entity.setLocationAndAngles((x + offX) + 0.5F, y, (z + offZ) + 0.5F, entity.rotationYaw, entity.rotationPitch);
|
||||||
|
petPathfinder.clearPath();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
protected boolean canTeleport(int x, int y, int z, int xOffset, int zOffset) {
|
||||||
|
if (xOffset < 1 || zOffset < 1 || xOffset > 3 || zOffset > 3) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos pos = new BlockPos(x + xOffset, y - 1, z + zOffset);
|
||||||
|
IBlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
|
return state.getBlockFaceShape(world, pos, EnumFacing.DOWN) == BlockFaceShape.SOLID
|
||||||
|
&& state.canEntitySpawn(entity)
|
||||||
|
&& world.isAirBlock(pos.up())
|
||||||
|
&& world.isAirBlock(pos.up(2));
|
||||||
|
}
|
||||||
|
}
|
|
@ -104,7 +104,9 @@ public class ModelGem extends ModelBase {
|
||||||
|
|
||||||
setLightingConditionsBrightness(0xF0F0);
|
setLightingConditionsBrightness(0xF0F0);
|
||||||
|
|
||||||
Color.glColor(spell.getEffect().getTint(), 1);
|
if (spell.hasEffect()) {
|
||||||
|
Color.glColor(spell.getEffect().getTint(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
int tiers = Math.min(spell.getCurrentLevel(), 5);
|
int tiers = Math.min(spell.getCurrentLevel(), 5);
|
||||||
|
|
||||||
|
@ -144,10 +146,7 @@ public class ModelGem extends ModelBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderOverlay(float grow, float scale) {
|
protected void renderOverlay(float grow, float scale) {
|
||||||
|
|
||||||
|
|
||||||
body.render(scale);
|
body.render(scale);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setLightingConditionsBrightness(int brightness) {
|
private void setLightingConditionsBrightness(int brightness) {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.minelittlepony.unicopia.network;
|
package com.minelittlepony.unicopia.network;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.spell.ICaster;
|
import com.minelittlepony.unicopia.spell.ICaster;
|
||||||
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
import com.minelittlepony.unicopia.spell.IMagicEffect;
|
||||||
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
import com.minelittlepony.unicopia.spell.SpellRegistry;
|
||||||
|
@ -9,6 +11,8 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.network.datasync.DataParameter;
|
import net.minecraft.network.datasync.DataParameter;
|
||||||
|
|
||||||
public class EffectSync<T extends EntityLivingBase> {
|
public class EffectSync<T extends EntityLivingBase> {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private IMagicEffect effect;
|
private IMagicEffect effect;
|
||||||
|
|
||||||
private final ICaster<T> owned;
|
private final ICaster<T> owned;
|
||||||
|
@ -49,7 +53,7 @@ public class EffectSync<T extends EntityLivingBase> {
|
||||||
return effect;
|
return effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(IMagicEffect effect) {
|
public void set(@Nullable IMagicEffect effect) {
|
||||||
if (this.effect != null && this.effect != effect) {
|
if (this.effect != null && this.effect != effect) {
|
||||||
this.effect.setDead();
|
this.effect.setDead();
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,12 +327,13 @@ class PlayerCapabilities implements IPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEffect(IMagicEffect effect) {
|
public void setEffect(@Nullable IMagicEffect effect) {
|
||||||
effectDelegate.set(effect);
|
effectDelegate.set(effect);
|
||||||
|
|
||||||
sendCapabilities(true);
|
sendCapabilities(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IMagicEffect getEffect() {
|
public IMagicEffect getEffect() {
|
||||||
return effectDelegate.get();
|
return effectDelegate.get();
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
package com.minelittlepony.unicopia.spell;
|
package com.minelittlepony.unicopia.spell;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
|
||||||
public abstract class AbstractSpell implements IMagicEffect {
|
public abstract class AbstractSpell implements IMagicEffect {
|
||||||
|
|
||||||
protected boolean isDead = false;
|
protected boolean isDead = false;
|
||||||
|
|
||||||
|
private int strength = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCurrentLevel() {
|
public int getCurrentLevel() {
|
||||||
return 0;
|
return strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentLevel(int level) {
|
public void setCurrentLevel(int level) {
|
||||||
|
strength = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,4 +32,16 @@ public abstract class AbstractSpell implements IMagicEffect {
|
||||||
public boolean getDead() {
|
public boolean getDead() {
|
||||||
return isDead;
|
return isDead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
compound.setBoolean("dead", isDead);
|
||||||
|
compound.setInteger("spell_strength", strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
isDead = compound.getBoolean("dead");
|
||||||
|
strength = compound.getInteger("spell_strength");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.player.IOwned;
|
import com.minelittlepony.unicopia.player.IOwned;
|
||||||
import com.minelittlepony.util.shape.IShape;
|
import com.minelittlepony.util.shape.IShape;
|
||||||
import com.minelittlepony.util.vector.VecHelper;
|
import com.minelittlepony.util.vector.VecHelper;
|
||||||
|
@ -17,8 +19,9 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned {
|
public interface ICaster<E extends EntityLivingBase> extends IOwned<E>, ILevelled, IAligned {
|
||||||
|
|
||||||
void setEffect(IMagicEffect effect);
|
void setEffect(@Nullable IMagicEffect effect);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
IMagicEffect getEffect();
|
IMagicEffect getEffect();
|
||||||
|
|
||||||
default boolean hasEffect() {
|
default boolean hasEffect() {
|
||||||
|
|
|
@ -83,4 +83,8 @@ public interface IMagicEffect extends InbtSerialisable, ILevelled, IAligned {
|
||||||
default boolean allowAI() {
|
default boolean allowAI() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default IMagicEffect copy() {
|
||||||
|
return SpellRegistry.instance().copyInstance(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class SpellCharge extends AbstractSpell {
|
public class SpellCharge extends AbstractSpell {
|
||||||
|
|
||||||
private int desiredLevel = 0;
|
|
||||||
|
|
||||||
boolean searching = true;
|
boolean searching = true;
|
||||||
|
|
||||||
private UUID targettedEntityId;
|
private UUID targettedEntityId;
|
||||||
|
@ -115,30 +113,21 @@ public class SpellCharge extends AbstractSpell {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentLevel() {
|
|
||||||
return desiredLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCurrentLevel(int level) {
|
|
||||||
desiredLevel = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
|
||||||
if (targettedEntityId != null) {
|
if (targettedEntityId != null) {
|
||||||
compound.setUniqueId("target", targettedEntityId);
|
compound.setUniqueId("target", targettedEntityId);
|
||||||
}
|
}
|
||||||
compound.setInteger("level", desiredLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
|
||||||
if (compound.hasKey("target")) {
|
if (compound.hasKey("target")) {
|
||||||
targettedEntityId = compound.getUniqueId("target");
|
targettedEntityId = compound.getUniqueId("target");
|
||||||
}
|
}
|
||||||
|
|
||||||
desiredLevel = compound.getInteger("level");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,7 @@ public class SpellDisguise extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
|
||||||
compound.setString("entityId", entityId);
|
compound.setString("entityId", entityId);
|
||||||
compound.setBoolean("dead", getDead());
|
compound.setBoolean("dead", getDead());
|
||||||
|
@ -225,6 +226,8 @@ public class SpellDisguise extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
|
||||||
String newId = compound.getString("entityId");
|
String newId = compound.getString("entityId");
|
||||||
|
|
||||||
if (!newId.contentEquals(entityId)) {
|
if (!newId.contentEquals(entityId)) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class SpellDrake extends AbstractSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getDead() {
|
public boolean getDead() {
|
||||||
return super.getDead() || (piggyBackSpell != null && piggyBackSpell.getDead());
|
return super.getDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,28 +58,36 @@ public class SpellDrake extends AbstractSpell {
|
||||||
if (firstUpdate) {
|
if (firstUpdate) {
|
||||||
firstUpdate = false;
|
firstUpdate = false;
|
||||||
|
|
||||||
if (source.getOwner() instanceof EntitySpell) {
|
if (source.getEntity() instanceof EntitySpell) {
|
||||||
EntitySpell living = (EntitySpell)source.getOwner();
|
EntitySpell living = (EntitySpell)source.getEntity();
|
||||||
|
|
||||||
((PathNavigateGround)living.getNavigator()).setCanSwim(false);
|
((PathNavigateGround)living.getNavigator()).setCanSwim(false);
|
||||||
living.tasks.addTask(1, new EntityAISwimming(living));
|
living.tasks.addTask(1, new EntityAISwimming(living));
|
||||||
living.tasks.addTask(2, new EntityAIFollowCaster(source, 1, 4, 6));
|
living.tasks.addTask(2, new EntityAIFollowCaster<>(source, 1, 4, 70));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (piggyBackSpell == null) {
|
if (!source.getWorld().isRemote) {
|
||||||
AxisAlignedBB bb = EFFECT_BOUNDS.offset(source.getOriginVector());
|
|
||||||
|
|
||||||
source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e -> e instanceof EntitySpell).stream()
|
if (piggyBackSpell == null) {
|
||||||
.map(i -> (EntitySpell)i)
|
AxisAlignedBB bb = EFFECT_BOUNDS.offset(source.getOriginVector());
|
||||||
.filter(i -> i.getEffect() != null && !(i.getEffect() instanceof SpellDrake))
|
|
||||||
.findFirst().ifPresent(i -> {
|
source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e -> e instanceof EntitySpell).stream()
|
||||||
piggyBackSpell = i.getEffect();
|
.map(i -> (EntitySpell)i)
|
||||||
i.setEffect(null);
|
.filter(i -> i.hasEffect() && !(i.getEffect() instanceof SpellDrake))
|
||||||
});
|
.findFirst().ifPresent(i -> {
|
||||||
|
piggyBackSpell = i.getEffect().copy();
|
||||||
|
piggyBackSpell.onPlaced(source);
|
||||||
|
i.setEffect(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return piggyBackSpell != null && piggyBackSpell.update(source, level);
|
if (piggyBackSpell != null) {
|
||||||
|
piggyBackSpell.update(source, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -89,7 +97,10 @@ public class SpellDrake extends AbstractSpell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
|
||||||
if (piggyBackSpell != null) {
|
if (piggyBackSpell != null) {
|
||||||
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(piggyBackSpell));
|
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(piggyBackSpell));
|
||||||
}
|
}
|
||||||
|
@ -97,6 +108,8 @@ public class SpellDrake extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
|
||||||
if (compound.hasKey("effect")) {
|
if (compound.hasKey("effect")) {
|
||||||
piggyBackSpell = SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"));
|
piggyBackSpell = SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,6 +290,8 @@ public class SpellPortal extends AbstractSpell implements IUseAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
public void writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
|
||||||
if (destinationPos != null) {
|
if (destinationPos != null) {
|
||||||
compound.setTag("destination", InbtSerialisable.writeBlockPos(destinationPos));
|
compound.setTag("destination", InbtSerialisable.writeBlockPos(destinationPos));
|
||||||
}
|
}
|
||||||
|
@ -307,6 +309,8 @@ public class SpellPortal extends AbstractSpell implements IUseAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
|
||||||
if (compound.hasKey("destination")) {
|
if (compound.hasKey("destination")) {
|
||||||
destinationPos = InbtSerialisable.readBlockPos(compound.getCompoundTag("destination"));
|
destinationPos = InbtSerialisable.readBlockPos(compound.getCompoundTag("destination"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,11 @@ public class SpellRegistry {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends IMagicEffect> T copyInstance(T effect) {
|
||||||
|
return (T)createEffectFromNBT(serializeEffectToNBT(effect));
|
||||||
|
}
|
||||||
|
|
||||||
public IMagicEffect createEffectFromNBT(NBTTagCompound compound) {
|
public IMagicEffect createEffectFromNBT(NBTTagCompound compound) {
|
||||||
if (compound.hasKey("effect_id")) {
|
if (compound.hasKey("effect_id")) {
|
||||||
IMagicEffect effect = getSpellFromName(compound.getString("effect_id"));
|
IMagicEffect effect = getSpellFromName(compound.getString("effect_id"));
|
||||||
|
|
|
@ -13,23 +13,10 @@ import net.minecraft.entity.Entity;
|
||||||
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.init.SoundEvents;
|
import net.minecraft.init.SoundEvents;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class SpellShield extends AbstractSpell {
|
public class SpellShield extends AbstractSpell {
|
||||||
|
|
||||||
private int strength = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCurrentLevel() {
|
|
||||||
return strength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCurrentLevel(int level) {
|
|
||||||
strength = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "shield";
|
return "shield";
|
||||||
|
@ -52,43 +39,51 @@ public class SpellShield extends AbstractSpell {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ICaster<?> source, int level) {
|
public void render(ICaster<?> source, int level) {
|
||||||
spawnParticles(source, 4 + (level * 2));
|
level = 4 + (level * 2);
|
||||||
}
|
|
||||||
|
|
||||||
protected void spawnParticles(ICaster<?> source, int strength) {
|
source.spawnParticles(new Sphere(true, level), level * 6, pos -> {
|
||||||
source.spawnParticles(new Sphere(true, strength), strength * 6, pos -> {
|
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0);
|
||||||
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean updateOnPerson(ICaster<?> source) {
|
public boolean updateOnPerson(ICaster<?> source) {
|
||||||
update(source, strength);
|
if (super.updateOnPerson(source)) {
|
||||||
|
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
|
||||||
if (source.getEntity().getEntityWorld().getWorldTime() % 50 == 0) {
|
double radius = 4 + (getCurrentLevel() * 2);
|
||||||
double radius = 4 + (strength * 2);
|
if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) {
|
||||||
if (!IPower.takeFromPlayer((EntityPlayer)source.getOwner(), radius/4)) {
|
setDead();
|
||||||
setDead();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !getDead();
|
return !getDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected double getDrawDropOffRange(int level) {
|
||||||
|
return 4 + (level * 2);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(ICaster<?> source, int level) {
|
public boolean update(ICaster<?> source, int level) {
|
||||||
double radius = 4 + (level * 2);
|
double radius = getDrawDropOffRange(level);
|
||||||
|
|
||||||
Entity owner = source.getOwner();
|
Entity owner = source.getOwner();
|
||||||
|
|
||||||
boolean ownerIsValid = source.getAffinity() != SpellAffinity.BAD && Predicates.MAGI.test(owner);
|
boolean ownerIsValid = source.getAffinity() != SpellAffinity.BAD && Predicates.MAGI.test(owner);
|
||||||
|
|
||||||
|
Vec3d origin = source.getOriginVector();
|
||||||
|
|
||||||
source.findAllEntitiesInRange(radius)
|
source.findAllEntitiesInRange(radius)
|
||||||
.filter(entity -> !(ownerIsValid && entity.equals(owner)))
|
.filter(entity -> !(ownerIsValid && entity.equals(owner)))
|
||||||
.forEach(i -> {
|
.forEach(i -> {
|
||||||
double dist = Math.sqrt(i.getDistanceSq(source.getOrigin()));
|
try {
|
||||||
|
double dist = i.getPositionVector().distanceTo(origin);
|
||||||
|
|
||||||
applyRadialEffect(source, i, dist, radius);
|
applyRadialEffect(source, i, dist, radius);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -107,10 +102,12 @@ public class SpellShield extends AbstractSpell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (target instanceof EntityLivingBase) {
|
} else if (target instanceof EntityLivingBase) {
|
||||||
double force = Math.min(0.25F, distance);
|
double force = Math.max(0.1, radius / 4);
|
||||||
|
|
||||||
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
|
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
|
||||||
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));
|
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));
|
||||||
|
} else {
|
||||||
|
force *= 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
applyForce(pos, target, force, distance);
|
applyForce(pos, target, force, distance);
|
||||||
|
@ -121,12 +118,12 @@ public class SpellShield extends AbstractSpell {
|
||||||
* Applies a force to the given entity based on distance from the source.
|
* Applies a force to the given entity based on distance from the source.
|
||||||
*/
|
*/
|
||||||
protected void applyForce(Vec3d pos, Entity target, double force, double distance) {
|
protected void applyForce(Vec3d pos, Entity target, double force, double distance) {
|
||||||
pos = target.getPositionVector().subtract(pos);
|
pos = target.getPositionVector().subtract(pos).normalize().scale(force);
|
||||||
|
|
||||||
target.addVelocity(
|
target.addVelocity(
|
||||||
force / pos.x,
|
pos.x,
|
||||||
force / pos.y + (distance < 1 ? distance : 0),
|
pos.y + (distance < 1 ? distance : 0),
|
||||||
force / pos.z
|
pos.z
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,14 +160,4 @@ public class SpellShield extends AbstractSpell {
|
||||||
ProjectileUtil.setThrowableHeading(projectile, normal, (float)motion.length(), 0);
|
ProjectileUtil.setThrowableHeading(projectile, normal, (float)motion.length(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToNBT(NBTTagCompound compound) {
|
|
||||||
compound.setInteger("spell_strength", strength);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readFromNBT(NBTTagCompound compound) {
|
|
||||||
strength = compound.getInteger("spell_strength");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,25 @@ public class SpellVortex extends SpellShield {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void spawnParticles(ICaster<?> source, int strength) {
|
public void render(ICaster<?> source, int level) {
|
||||||
|
level = 4 + (level * 2);
|
||||||
Vec3d pos = source.getOriginVector();
|
Vec3d pos = source.getOriginVector();
|
||||||
|
|
||||||
source.spawnParticles(new Sphere(false, strength), strength * 9, p -> {
|
source.spawnParticles(new Sphere(false, level), level * 9, p -> {
|
||||||
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, p, p.subtract(pos));
|
Particles.instance().spawnParticle(UParticles.UNICORN_MAGIC, false, p, p.subtract(pos));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected double getDrawDropOffRange(int level) {
|
||||||
|
return 10 + (level * 2);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyRadialEffect(ICaster<?> source, Entity target, double distance, double radius) {
|
protected void applyRadialEffect(ICaster<?> source, Entity target, double distance, double radius) {
|
||||||
Vec3d pos = source.getOriginVector();
|
Vec3d pos = source.getOriginVector();
|
||||||
|
|
||||||
double force = 4 / distance;
|
double force = 2.5F / distance;
|
||||||
|
|
||||||
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
|
if (source.getAffinity() != SpellAffinity.BAD && target instanceof EntityPlayer) {
|
||||||
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));
|
force *= calculateAdjustedForce(PlayerSpeciesList.instance().getPlayer((EntityPlayer)target));
|
||||||
|
|
Loading…
Reference in a new issue