From 9a610cc023a168c1dd8f3cfe495c68fa35b15c16 Mon Sep 17 00:00:00 2001 From: WayofTime Date: Thu, 31 Dec 2015 16:01:47 -0500 Subject: [PATCH] Implemented Well of Suffering. Tweaked AreaDescriptor slightly. --- .../bloodmagic/api/ritual/AreaDescriptor.java | 26 +++- .../bloodmagic/registry/ModRituals.java | 3 + .../ritual/RitualWellOfSuffering.java | 140 ++++++++++++++++++ 3 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 src/main/java/WayofTime/bloodmagic/ritual/RitualWellOfSuffering.java diff --git a/src/main/java/WayofTime/bloodmagic/api/ritual/AreaDescriptor.java b/src/main/java/WayofTime/bloodmagic/api/ritual/AreaDescriptor.java index 931b5707..f0da7bd1 100644 --- a/src/main/java/WayofTime/bloodmagic/api/ritual/AreaDescriptor.java +++ b/src/main/java/WayofTime/bloodmagic/api/ritual/AreaDescriptor.java @@ -7,7 +7,7 @@ import java.util.List; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; -public class AreaDescriptor +public abstract class AreaDescriptor { public List getContainedPositions(BlockPos pos) { @@ -19,6 +19,10 @@ public class AreaDescriptor return null; } + public abstract void resetCache(); + + public abstract boolean isWithinArea(BlockPos pos); + public static class Rectangle extends AreaDescriptor { private BlockPos minimumOffset; @@ -27,6 +31,8 @@ public class AreaDescriptor private ArrayList blockPosCache = new ArrayList(); private BlockPos cachedPosition = new BlockPos(0, 0, 0); + private boolean cache = true; + /** * This constructor takes in the minimum and maximum BlockPos. The * maximum offset is non-inclusive, meaning if you pass in (0,0,0) and @@ -53,7 +59,7 @@ public class AreaDescriptor @Override public List getContainedPositions(BlockPos pos) { - if (!pos.equals(cachedPosition) || blockPosCache.isEmpty()) + if (!cache || !pos.equals(cachedPosition) || blockPosCache.isEmpty()) { ArrayList posList = new ArrayList(); @@ -95,5 +101,21 @@ public class AreaDescriptor this.maximumOffset = new BlockPos(Math.max(offset1.getX(), offset2.getX()), Math.max(offset1.getY(), offset2.getY()), Math.max(offset1.getZ(), offset2.getZ())); blockPosCache = new ArrayList(); } + + @Override + public void resetCache() + { + this.blockPosCache = new ArrayList(); + } + + @Override + public boolean isWithinArea(BlockPos pos) + { + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + + return x >= minimumOffset.getX() && x < maximumOffset.getX() && y >= minimumOffset.getY() && y < maximumOffset.getY() && z >= minimumOffset.getZ() && z < maximumOffset.getZ(); + } } } diff --git a/src/main/java/WayofTime/bloodmagic/registry/ModRituals.java b/src/main/java/WayofTime/bloodmagic/registry/ModRituals.java index d9f5ed32..2a93789c 100644 --- a/src/main/java/WayofTime/bloodmagic/registry/ModRituals.java +++ b/src/main/java/WayofTime/bloodmagic/registry/ModRituals.java @@ -17,6 +17,7 @@ public class ModRituals public static Ritual lavaRitual; public static Ritual greenGroveRitual; public static Ritual jumpRitual; + public static Ritual sufferingRitual; public static ImperfectRitual imperfectNight; public static ImperfectRitual imperfectRain; @@ -30,12 +31,14 @@ public class ModRituals lavaRitual = new RitualLava(); greenGroveRitual = new RitualGreenGrove(); jumpRitual = new RitualJumping(); + sufferingRitual = new RitualWellOfSuffering(); RitualRegistry.registerRitual(testRitual, testRitual.getName()); RitualRegistry.registerRitual(waterRitual, waterRitual.getName()); RitualRegistry.registerRitual(lavaRitual, lavaRitual.getName()); RitualRegistry.registerRitual(greenGroveRitual, greenGroveRitual.getName()); RitualRegistry.registerRitual(jumpRitual, jumpRitual.getName()); + RitualRegistry.registerRitual(sufferingRitual, sufferingRitual.getName()); } public static void initImperfectRituals() diff --git a/src/main/java/WayofTime/bloodmagic/ritual/RitualWellOfSuffering.java b/src/main/java/WayofTime/bloodmagic/ritual/RitualWellOfSuffering.java new file mode 100644 index 00000000..87da44fa --- /dev/null +++ b/src/main/java/WayofTime/bloodmagic/ritual/RitualWellOfSuffering.java @@ -0,0 +1,140 @@ +package WayofTime.bloodmagic.ritual; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraft.util.DamageSource; +import net.minecraft.world.World; +import WayofTime.bloodmagic.api.Constants; +import WayofTime.bloodmagic.api.network.SoulNetwork; +import WayofTime.bloodmagic.api.ritual.AreaDescriptor; +import WayofTime.bloodmagic.api.ritual.EnumRuneType; +import WayofTime.bloodmagic.api.ritual.IMasterRitualStone; +import WayofTime.bloodmagic.api.ritual.Ritual; +import WayofTime.bloodmagic.api.ritual.RitualComponent; +import WayofTime.bloodmagic.api.util.helper.NetworkHelper; +import WayofTime.bloodmagic.tile.TileAltar; + +public class RitualWellOfSuffering extends Ritual +{ + public static final String ALTAR_RANGE = "altar"; + public static final String DAMAGE_RANGE = "damage"; + + public static final int SACRIFICE_AMOUNT = 20; + + public BlockPos altarOffsetPos = new BlockPos(0, 0, 0); //TODO: Save! + + public RitualWellOfSuffering() + { + super("ritualWellOfSuffering", 0, 1000, "ritual." + Constants.Mod.MODID + ".wellOfSufferingRitual"); + addBlockRange(ALTAR_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-5, -10, -5), 11, 21, 11)); + addBlockRange(DAMAGE_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-10, -10, -10), 21)); + } + + @Override + public void performRitual(IMasterRitualStone masterRitualStone) + { + World world = masterRitualStone.getWorld(); + SoulNetwork network = NetworkHelper.getSoulNetwork(masterRitualStone.getOwner(), world); + int currentEssence = network.getCurrentEssence(); + + if (currentEssence < getRefreshCost()) + return; + + BlockPos pos = masterRitualStone.getPos(); + + int maxEffects = currentEssence / getRefreshCost(); + int totalEffects = 0; + + BlockPos altarPos = pos.add(altarOffsetPos); + + TileEntity tile = world.getTileEntity(altarPos); + + AreaDescriptor altarRange = getBlockRange(ALTAR_RANGE); + + if (!altarRange.isWithinArea(altarOffsetPos) || !(tile instanceof TileAltar)) + { + for (BlockPos newPos : altarRange.getContainedPositions(pos)) + { + TileEntity nextTile = world.getTileEntity(newPos); + if (nextTile instanceof TileAltar) + { + tile = nextTile; + altarOffsetPos = newPos.subtract(pos); + + altarRange.resetCache(); + break; + } + } + } + + if (tile instanceof TileAltar) + { + TileAltar tileAltar = (TileAltar) tile; + + AreaDescriptor damageRange = getBlockRange(DAMAGE_RANGE); + AxisAlignedBB range = damageRange.getAABB(pos); + + List entities = world.getEntitiesWithinAABB(EntityLivingBase.class, range); + + for (EntityLivingBase entity : entities) + { + if (entity.isEntityAlive() && !(entity instanceof EntityPlayer)) + { + if (entity.attackEntityFrom(DamageSource.outOfWorld, 1)) + { + tileAltar.sacrificialDaggerCall(SACRIFICE_AMOUNT, true); + + totalEffects++; + + if (totalEffects >= maxEffects) + { + break; + } + } + } + } + } + + network.syphon(getRefreshCost() * totalEffects); + } + + @Override + public int getRefreshTime() + { + return 25; + } + + @Override + public int getRefreshCost() + { + return 2; + } + + @Override + public ArrayList getComponents() + { + ArrayList components = new ArrayList(); + + this.addCornerRunes(components, 1, 0, EnumRuneType.FIRE); + this.addCornerRunes(components, 2, -1, EnumRuneType.FIRE); + this.addParallelRunes(components, 2, -1, EnumRuneType.EARTH); + this.addCornerRunes(components, -3, -1, EnumRuneType.DUSK); + this.addOffsetRunes(components, 2, 4, -1, EnumRuneType.WATER); + this.addOffsetRunes(components, 1, 4, 0, EnumRuneType.WATER); + this.addParallelRunes(components, 4, 1, EnumRuneType.AIR); + + return components; + } + + @Override + public Ritual getNewCopy() + { + return new RitualWellOfSuffering(); + } +}