Added Gem of Assistance and Gem of inferno

This commit is contained in:
Sollace 2019-02-05 11:24:48 +02:00
parent b976c3d0f3
commit cfc78f2f32
7 changed files with 282 additions and 6 deletions

View file

@ -0,0 +1,48 @@
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 net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.EntityAIFollow;
public class EntityAIFollowCaster extends EntityAIFollow {
protected final ICaster<?> entity;
private static Field __followPredicate;
static {
try {
Field f = EntityAIFollow.class.getDeclaredFields()[1];
f.setAccessible(true);
__followPredicate = RegistryLockSpinner.makeNonFinal(f);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
__followPredicate = null;
}
}
public EntityAIFollowCaster(ICaster<?> caster, double walkSpeed, float maxDistance, float area) {
super((EntityLiving)caster.getEntity(), walkSpeed, maxDistance, area);
entity = caster;
if (__followPredicate != null) {
try {
__followPredicate.set(this, (Predicate<EntityLivingBase>)(e -> {
Entity owner = caster.getOwner();
return e != null && (e == owner || (owner != null && owner.getUniqueID().equals(e.getUniqueID())));
}));
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

View file

@ -71,7 +71,7 @@ public final class RegistryLockSpinner {
}
@FUF(reason = "Not exactly forge's fault, but it was would be nice of them to not leave these as final")
private static Field makeNonFinal(Field f) throws IllegalArgumentException, IllegalAccessException {
public static Field makeNonFinal(Field f) throws IllegalArgumentException, IllegalAccessException {
initModifiersField();
if (Modifier.isFinal(f.getModifiers()) && modifieres != null) {
modifieres.setInt(f, f.getModifiers() & ~Modifier.FINAL);

View file

@ -0,0 +1,104 @@
package com.minelittlepony.unicopia.spell;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.entity.EntitySpell;
import com.minelittlepony.unicopia.entity.ai.EntityAIFollowCaster;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathNavigateGround;
import net.minecraft.util.math.AxisAlignedBB;
public class SpellDrake extends AbstractSpell {
private static final AxisAlignedBB EFFECT_BOUNDS = new AxisAlignedBB(-2, -2, -2, 2, 2, 2);
@Nullable
private IMagicEffect piggyBackSpell;
private boolean firstUpdate = true;
@Override
public String getName() {
return "drake";
}
@Override
public SpellAffinity getAffinity() {
return SpellAffinity.NEUTRAL;
}
@Override
public int getTint() {
return 0xFAEBD7;
}
@Override
public void setDead() {
super.setDead();
if (piggyBackSpell != null) {
piggyBackSpell.setDead();
}
}
@Override
public boolean allowAI() {
return true;
}
public boolean getDead() {
return super.getDead() || (piggyBackSpell != null && piggyBackSpell.getDead());
}
@Override
public boolean update(ICaster<?> source, int level) {
if (firstUpdate) {
firstUpdate = false;
if (source.getOwner() instanceof EntitySpell) {
EntitySpell living = (EntitySpell)source.getOwner();
((PathNavigateGround)living.getNavigator()).setCanSwim(false);
living.tasks.addTask(1, new EntityAISwimming(living));
living.tasks.addTask(2, new EntityAIFollowCaster(source, 1, 4, 6));
}
}
if (piggyBackSpell == null) {
AxisAlignedBB bb = EFFECT_BOUNDS.offset(source.getOriginVector());
source.getWorld().getEntitiesInAABBexcluding(source.getEntity(), bb, e -> e instanceof EntitySpell).stream()
.map(i -> (EntitySpell)i)
.filter(i -> i.getEffect() != null && !(i.getEffect() instanceof SpellDrake))
.findFirst().ifPresent(i -> {
piggyBackSpell = i.getEffect();
i.setEffect(null);
});
}
return piggyBackSpell != null && piggyBackSpell.update(source, level);
}
@Override
public void render(ICaster<?> source, int level) {
if (piggyBackSpell != null) {
piggyBackSpell.render(source, level);
}
}
public void writeToNBT(NBTTagCompound compound) {
if (piggyBackSpell != null) {
compound.setTag("effect", SpellRegistry.instance().serializeEffectToNBT(piggyBackSpell));
}
}
@Override
public void readFromNBT(NBTTagCompound compound) {
if (compound.hasKey("effect")) {
piggyBackSpell = SpellRegistry.instance().createEffectFromNBT(compound.getCompoundTag("effect"));
}
}
}

View file

@ -100,11 +100,11 @@ public class SpellFire extends AbstractSpell implements IUseAction, IDispenceabl
boolean result = false;
if (player == null || player.isSneaking()) {
result = applyBlocks(player, world, pos);
result = applyBlocks(world, pos);
} else {
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
result |= applyBlocks(player, world, i);
result |= applyBlocks(world, i);
}
}
@ -127,7 +127,7 @@ public class SpellFire extends AbstractSpell implements IUseAction, IDispenceabl
boolean result = false;
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
result |= applyBlocks(null, source.getWorld(), i);
result |= applyBlocks(source.getWorld(), i);
}
if (!result) {
@ -137,7 +137,7 @@ public class SpellFire extends AbstractSpell implements IUseAction, IDispenceabl
return result ? SpellCastResult.NONE : SpellCastResult.DEFAULT;
}
protected boolean applyBlocks(EntityPlayer owner, World world, BlockPos pos) {
protected boolean applyBlocks(World world, BlockPos pos) {
IBlockState state = world.getBlockState(pos);
Block id = state.getBlock();
@ -191,7 +191,7 @@ public class SpellFire extends AbstractSpell implements IUseAction, IDispenceabl
return false;
}
protected boolean applyEntities(EntityPlayer owner, World world, BlockPos pos) {
protected boolean applyEntities(Entity owner, World world, BlockPos pos) {
return VecHelper
.findAllEntitiesInRange(owner, world, pos, 3)
.filter(i -> applyEntitySingle(owner, world, i))

View file

@ -0,0 +1,113 @@
package com.minelittlepony.unicopia.spell;
import com.minelittlepony.util.MagicalDamageSource;
import com.minelittlepony.util.blockstate.IStateMapping;
import com.minelittlepony.util.blockstate.StateMapList;
import com.minelittlepony.util.shape.IShape;
import com.minelittlepony.util.shape.Sphere;
import net.minecraft.block.BlockBush;
import net.minecraft.block.BlockOre;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class SpellInferno extends SpellFire {
public final StateMapList hellFireAffected = new StateMapList();
public SpellInferno() {
hellFireAffected.add(IStateMapping.build(
s -> s.getBlock() == Blocks.GRASS || s.getBlock() == Blocks.DIRT || s.getBlock() == Blocks.STONE,
s -> Blocks.NETHERRACK.getDefaultState()));
hellFireAffected.replaceBlock(Blocks.SAND, Blocks.SOUL_SAND);
hellFireAffected.replaceBlock(Blocks.GRAVEL, Blocks.SOUL_SAND);
hellFireAffected.add(IStateMapping.build(
s -> s.getMaterial() == Material.WATER,
s -> Blocks.OBSIDIAN.getDefaultState()));
hellFireAffected.add(IStateMapping.build(
s -> s.getBlock() instanceof BlockBush,
s -> Blocks.NETHER_WART.getDefaultState()));
hellFireAffected.add(IStateMapping.build(
s -> (s.getBlock() != Blocks.QUARTZ_ORE) && (s.getBlock() instanceof BlockOre),
s -> Blocks.QUARTZ_ORE.getDefaultState()));
}
@Override
public String getName() {
return "inferno";
}
@Override
public SpellAffinity getAffinity() {
return SpellAffinity.BAD;
}
@Override
public int getTint() {
return 0xFF8C00;
}
@Override
public SpellCastResult onUse(ItemStack stack, SpellAffinity affinity, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) {
return SpellCastResult.PLACE;
}
@Override
public boolean update(ICaster<?> source, int level) {
World w = source.getWorld();
if (!w.isRemote) {
int radius = 4 + (level * 4);
IShape shape = new Sphere(false, radius);
Vec3d origin = source.getOriginVector();
for (int i = 0; i < radius; i++) {
BlockPos pos = new BlockPos(shape.computePoint(w.rand).add(origin));
IBlockState state = w.getBlockState(pos);
IBlockState newState = hellFireAffected.getConverted(state);
if (!state.equals(newState)) {
w.setBlockState(pos, newState, 3);
playEffect(w, pos);
}
}
shape = new Sphere(false, radius - 1);
for (int i = 0; i < radius * 2; i++) {
if (w.rand.nextInt(12) == 0) {
BlockPos pos = new BlockPos(shape.computePoint(w.rand).add(origin));
if (!applyBlocks(w, pos)) {
applyEntities(source.getOwner(), w, pos);
}
}
}
}
return false;
}
@Override
protected DamageSource getDamageCause(Entity target, EntityLivingBase attacker) {
if (attacker != null && attacker.getUniqueID().equals(target.getUniqueID())) {
return MagicalDamageSource.causeMobDamage("fire.own", null);
}
return MagicalDamageSource.causeMobDamage("fire", attacker);
}
}

View file

@ -40,6 +40,8 @@ public class SpellRegistry {
registerSpell(SpellDisguise::new);
registerSpell(SpellNecromancy::new);
registerSpell(SpellAwkward::new);
registerSpell(SpellInferno::new);
registerSpell(SpellDrake::new);
}
@Nullable

View file

@ -51,6 +51,9 @@ spell.charge.tagline=Energy I
spell.ice.name=Frost
spell.ice.tagline=Ice I
spell.drake.name=Assistance
spell.drake.tagline=Helpfulness I
curse.shield.name=Repulsion
curse.shield.tagline=Hostility I
@ -63,6 +66,12 @@ curse.vortex.tagline=Torture I
curse.necromancy.name=Necromancy
curse.necromancy.tagline=Resurrection I
curse.drake.name=Assistance
curse.drake.tagline=Unhelpfulness I
curse.inferno.name=Inferno
curse.inferno.tagline=Fire II
item.spellbook.name=Spellbook
item.bag_of_holding.name=Bag of Holding