From 322419970bd409863e9ded08fbac6aca5858bde3 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 4 Feb 2019 21:24:10 +0200 Subject: [PATCH] Added the necromancy trap gem --- .../unicopia/spell/ICaster.java | 6 +- .../unicopia/spell/SpellNecromancy.java | 118 ++++++++++++++++++ .../unicopia/spell/SpellRegistry.java | 1 + .../resources/assets/unicopia/lang/en_US.lang | 2 +- 4 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java diff --git a/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java b/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java index dcd7b26e..6fecbbd7 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/ICaster.java @@ -51,12 +51,10 @@ public interface ICaster extends IOwned, ILevelle default void spawnParticles(IShape area, int count, Consumer particleSpawner) { Random rand = getWorld().rand; - double x = getEntity().posX; - double y = getEntity().posY; - double z = getEntity().posZ; + Vec3d pos = getOriginVector(); for (int i = 0; i < count; i++) { - particleSpawner.accept(area.computePoint(rand).add(x, y, z)); + particleSpawner.accept(area.computePoint(rand).add(pos)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java new file mode 100644 index 00000000..70b277ff --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellNecromancy.java @@ -0,0 +1,118 @@ +package com.minelittlepony.unicopia.spell; + +import java.util.List; + +import com.google.common.collect.Lists; +import com.minelittlepony.util.WorldEvent; +import com.minelittlepony.util.shape.IShape; +import com.minelittlepony.util.shape.Sphere; +import com.minelittlepony.util.vector.VecHelper; + +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityHusk; +import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; + +public class SpellNecromancy extends AbstractSpell { + + private final List> spawns = Lists.newArrayList( + EntityZombie::new, + EntityHusk::new, + EntityPigZombie::new + ); + + @Override + public String getName() { + return "necromancy"; + } + + @Override + public SpellAffinity getAffinity() { + return SpellAffinity.BAD; + } + + @Override + public int getTint() { + return 0; + } + + @Override + public boolean update(ICaster source, int level) { + + if (source.getWorld().isRemote || source.getWorld().getDifficulty() == EnumDifficulty.PEACEFUL) { + return true; + } + + + float additional = source.getWorld().getDifficultyForLocation(source.getOrigin()).getAdditionalDifficulty(); + + level++; + + IShape affectRegion = new Sphere(false, level * 4); + + if (source.getWorld().rand.nextInt(100) != 0) { + return true; + } + + Vec3d origin = source.getOriginVector(); + + if (VecHelper.findAllEntitiesInRange(source.getEntity(), source.getWorld(), source.getOrigin(), level * 4) + .filter(e -> e instanceof EntityZombie) + .count() >= 10 * (1 + additional)) { + return true; + } + + for (int i = 0; i < 10; i++) { + Vec3d pos = affectRegion.computePoint(source.getWorld().rand).add(origin); + + BlockPos loc = new BlockPos(pos); + + if (source.getWorld().isAirBlock(loc.up()) && !source.getWorld().isAirBlock(loc)) { + spawnMonster(source, pos); + + return true; + } + } + + + return true; + } + + protected void spawnMonster(ICaster source, Vec3d pos) { + int index = (int)MathHelper.nextDouble(source.getWorld().rand, 0, spawns.size()); + EntityLivingBase zombie = spawns.get(index).create(source.getWorld()); + zombie.setPosition(pos.x, pos.y, pos.z); + + + if (zombie instanceof EntityCreature) { + ((EntityCreature)zombie).setHomePosAndDistance(source.getOrigin(), 10); + } + zombie.motionY += 0.3F; + + source.getWorld().playEvent(WorldEvent.DOOR_BROKEN.getId(), zombie.getPosition(), 0); + + source.getWorld().spawnEntity(zombie); + } + + @Override + public void render(ICaster source, int level) { + IShape affectRegion = new Sphere(false, (1 + level) * 4); + + source.spawnParticles(affectRegion, 5, pos -> { + if (!source.getWorld().isAirBlock(new BlockPos(pos).down())) { + source.getWorld().spawnParticle(EnumParticleTypes.FLAME, pos.x, pos.y, pos.z, 0, 0, 0); + } + }); + } + + interface IMonsterSpawn { + T create(World w); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java index f8b5f4ae..d8f7f900 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellRegistry.java @@ -38,6 +38,7 @@ public class SpellRegistry { registerSpell(SpellPortal::new); registerSpell(SpellVortex::new); registerSpell(SpellDisguise::new); + registerSpell(SpellNecromancy::new); } @Nullable diff --git a/src/main/resources/assets/unicopia/lang/en_US.lang b/src/main/resources/assets/unicopia/lang/en_US.lang index 0d887441..4e4cee82 100644 --- a/src/main/resources/assets/unicopia/lang/en_US.lang +++ b/src/main/resources/assets/unicopia/lang/en_US.lang @@ -54,7 +54,7 @@ curse.shield.tagline=Hostility I curse.vortex.name=Suffering curse.vortex.tagline=Torture I -curse.necromany.name=Necromancy +curse.necromancy.name=Necromancy curse.necromancy.tagline=Resurrection I item.spellbook.name=Spellbook