mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Added Gem of Assistance and Gem of inferno
This commit is contained in:
parent
b976c3d0f3
commit
cfc78f2f32
7 changed files with 282 additions and 6 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
104
src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java
Normal file
104
src/main/java/com/minelittlepony/unicopia/spell/SpellDrake.java
Normal 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"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -40,6 +40,8 @@ public class SpellRegistry {
|
|||
registerSpell(SpellDisguise::new);
|
||||
registerSpell(SpellNecromancy::new);
|
||||
registerSpell(SpellAwkward::new);
|
||||
registerSpell(SpellInferno::new);
|
||||
registerSpell(SpellDrake::new);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue