diff --git a/src/main/java/WayofTime/bloodmagic/ritual/RitualGreenGrove.java b/src/main/java/WayofTime/bloodmagic/ritual/RitualGreenGrove.java index bb5ae341..a5fa8bab 100644 --- a/src/main/java/WayofTime/bloodmagic/ritual/RitualGreenGrove.java +++ b/src/main/java/WayofTime/bloodmagic/ritual/RitualGreenGrove.java @@ -5,10 +5,12 @@ import java.util.List; import java.util.Random; import net.minecraft.block.Block; +import net.minecraft.block.BlockFarmland; import net.minecraft.block.IGrowable; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.potion.PotionEffect; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -28,25 +30,32 @@ import WayofTime.bloodmagic.api.soul.EnumDemonWillType; import WayofTime.bloodmagic.api.util.helper.NetworkHelper; import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler; import WayofTime.bloodmagic.registry.ModPotions; +import WayofTime.bloodmagic.util.Utils; public class RitualGreenGrove extends Ritual { public static final String GROW_RANGE = "growing"; public static final String LEECH_RANGE = "leech"; + public static final String HYDRATE_RANGE = "hydrate"; public static double corrosiveWillDrain = 0.2; public static double rawWillDrain = 0.05; + public static double steadfastWillDrain = 0.05; public int refreshTime = 20; public static int defaultRefreshTime = 20; + public static IBlockState farmlandState = Blocks.FARMLAND.getDefaultState().withProperty(BlockFarmland.MOISTURE, 7); + public RitualGreenGrove() { super("ritualGreenGrove", 0, 5000, "ritual." + Constants.Mod.MODID + ".greenGroveRitual"); addBlockRange(GROW_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-1, 2, -1), 3, 1, 3)); addBlockRange(LEECH_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 0, 0), 1)); + addBlockRange(HYDRATE_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 0, 0), 1)); setMaximumVolumeAndDistanceOfRange(GROW_RANGE, 81, 4, 4); setMaximumVolumeAndDistanceOfRange(LEECH_RANGE, 0, 15, 15); + setMaximumVolumeAndDistanceOfRange(HYDRATE_RANGE, 0, 15, 15); } @Override @@ -70,6 +79,7 @@ public class RitualGreenGrove extends Ritual double corrosiveWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.CORROSIVE, willConfig); double rawWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.DEFAULT, willConfig); + double steadfastWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.STEADFAST, willConfig); refreshTime = getRefreshTimeForRawWill(rawWill); @@ -79,7 +89,7 @@ public class RitualGreenGrove extends Ritual AreaDescriptor growingRange = getBlockRange(GROW_RANGE); - for (BlockPos newPos : growingRange.getContainedPositions(masterRitualStone.getBlockPos())) + for (BlockPos newPos : growingRange.getContainedPositions(pos)) { IBlockState state = world.getBlockState(newPos); Block block = state.getBlock(); @@ -88,17 +98,24 @@ public class RitualGreenGrove extends Ritual { if (block instanceof IPlantable || block instanceof IGrowable) { - block.updateTick(world, newPos, state, new Random()); - totalGrowths++; - if (consumeRawWill) + if (world.rand.nextDouble() < 0.3) { - rawWill -= rawWillDrain; - rawDrain += rawWillDrain; + block.updateTick(world, newPos, state, new Random()); + IBlockState newState = world.getBlockState(newPos); + if (!newState.equals(state)) + { + totalGrowths++; + if (consumeRawWill) + { + rawWill -= rawWillDrain; + rawDrain += rawWillDrain; + } + } } } } - if (totalGrowths >= maxGrowths || (consumeRawWill && rawWill >= rawWillDrain)) + if (totalGrowths >= maxGrowths || (consumeRawWill && rawWill < rawWillDrain)) { break; } @@ -109,6 +126,53 @@ public class RitualGreenGrove extends Ritual WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.DEFAULT, rawDrain, true); } + AreaDescriptor hydrateRange = getBlockRange(HYDRATE_RANGE); + + double steadfastDrain = 0; + if (steadfastWill > steadfastWillDrain) + { + AxisAlignedBB aabb = hydrateRange.getAABB(pos); + steadfastDrain += steadfastWillDrain * Utils.plantSeedsInArea(world, aabb, 2, 1); + steadfastWill -= steadfastDrain; + + for (BlockPos newPos : hydrateRange.getContainedPositions(pos)) + { + if (steadfastWill < steadfastWillDrain) + { + break; + } + + IBlockState state = world.getBlockState(newPos); + Block block = state.getBlock(); + + boolean hydratedBlock = false; + if (block == Blocks.DIRT || block == Blocks.GRASS) + { + world.setBlockState(newPos, farmlandState); + hydratedBlock = true; + } else if (block == Blocks.FARMLAND) + { + int meta = block.getMetaFromState(state); + if (meta < 7) + { + world.setBlockState(newPos, farmlandState); + hydratedBlock = true; + } + } + + if (hydratedBlock) + { + steadfastWill -= steadfastWillDrain; + steadfastDrain += steadfastWillDrain; + } + } + } + + if (steadfastDrain > 0) + { + WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.STEADFAST, steadfastDrain, true); + } + double corrosiveDrain = 0; if (corrosiveWill > corrosiveWillDrain) { @@ -166,7 +230,7 @@ public class RitualGreenGrove extends Ritual @Override public int getRefreshCost() { - return 5; //TODO: Need to find a way to balance this + return 20; //TODO: Need to find a way to balance this } @Override @@ -183,7 +247,7 @@ public class RitualGreenGrove extends Ritual @Override public ITextComponent[] provideInformationOfRitualToPlayer(EntityPlayer player) { - return new ITextComponent[] { new TextComponentTranslation(this.getUnlocalizedName() + ".info"), new TextComponentTranslation(this.getUnlocalizedName() + ".corrosive.info") }; + return new ITextComponent[] { new TextComponentTranslation(this.getUnlocalizedName() + ".info"), new TextComponentTranslation(this.getUnlocalizedName() + ".default.info"), new TextComponentTranslation(this.getUnlocalizedName() + ".corrosive.info"), new TextComponentTranslation(this.getUnlocalizedName() + ".steadfast.info") }; } @Override diff --git a/src/main/java/WayofTime/bloodmagic/util/Utils.java b/src/main/java/WayofTime/bloodmagic/util/Utils.java index fb143eef..929f50b8 100644 --- a/src/main/java/WayofTime/bloodmagic/util/Utils.java +++ b/src/main/java/WayofTime/bloodmagic/util/Utils.java @@ -1,6 +1,7 @@ package WayofTime.bloodmagic.util; import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Set; import java.util.UUID; @@ -30,8 +31,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.common.IPlantable; import net.minecraftforge.common.ISpecialArmor; import net.minecraftforge.common.ISpecialArmor.ArmorProperties; import net.minecraftforge.common.MinecraftForge; @@ -79,6 +82,97 @@ public class Utils return false; } + public static int plantSeedsInArea(World world, AxisAlignedBB aabb, int horizontalRadius, int verticalRadius) + { + int placedBlocks = 0; + List itemEntities = world.getEntitiesWithinAABB(EntityItem.class, aabb); + + for (EntityItem itemEntity : itemEntities) + { + placedBlocks += plantEntityItem(itemEntity, horizontalRadius, verticalRadius); + } + + return placedBlocks; + } + + public static int plantItemStack(World world, BlockPos centralPos, ItemStack stack, int horizontalRadius, int verticalRadius) + { + if (stack == null || stack.stackSize <= 0) + { + return 0; + } + + Item item = stack.getItem(); + if (!(item instanceof IPlantable)) + { + return 0; + } + + int planted = 0; + + for (int hR = 0; hR <= horizontalRadius; hR++) + { + for (int vR = 0; vR <= verticalRadius; vR++) + { + for (int i = -hR; i <= hR; i++) + { + for (int k = -hR; k <= hR; k++) + { + for (int j = -vR; j <= vR; j += 2 * vR + (vR > 0 ? 0 : 1)) + { + if (!(Math.abs(i) == hR || Math.abs(k) == hR)) + { + continue; + } + + BlockPos newPos = centralPos.add(i, j, k); + if (world.isAirBlock(newPos)) + { + BlockPos offsetPos = newPos.offset(EnumFacing.DOWN); + IBlockState state = world.getBlockState(offsetPos); + if (state.getBlock().canSustainPlant(state, world, offsetPos, EnumFacing.UP, (IPlantable) item)) + { + IBlockState plantState = ((IPlantable) item).getPlant(world, newPos); + world.setBlockState(newPos, plantState, 3); + world.playEvent(2001, newPos, Block.getIdFromBlock(plantState.getBlock()) + (plantState.getBlock().getMetaFromState(plantState) << 12)); + stack.stackSize--; + planted++; + if (stack.stackSize <= 0) + { + return planted; + } + } + } + } + } + } + } + } + + return planted; + } + + public static int plantEntityItem(EntityItem itemEntity, int horizontalRadius, int verticalRadius) + { + if (itemEntity == null || itemEntity.isDead) + { + return 0; + } + + World world = itemEntity.worldObj; + BlockPos pos = itemEntity.getPosition(); + ItemStack stack = itemEntity.getEntityItem(); + + int planted = plantItemStack(world, pos, stack, horizontalRadius, verticalRadius); + + if (stack.stackSize <= 0) + { + itemEntity.setDead(); + } + + return planted; + } + public static int getDemonWillResolution(EntityPlayer player) { ItemStack[] mainInventory = player.inventory.mainInventory; diff --git a/src/main/resources/assets/bloodmagic/lang/en_US.lang b/src/main/resources/assets/bloodmagic/lang/en_US.lang index 2847db31..1fae2b36 100644 --- a/src/main/resources/assets/bloodmagic/lang/en_US.lang +++ b/src/main/resources/assets/bloodmagic/lang/en_US.lang @@ -491,6 +491,8 @@ ritual.BloodMagic.crushingRitual.destructive.info=(Destructive) Blocks are broke ritual.BloodMagic.crushingRitual.steadfast.info=(Steadfast) Causes all blocks that are broken to be picked up with silk touch. Overrides Fortune where applicable. ritual.BloodMagic.crushingRitual.corrosive.info=(Corrosive) All blocks are broken to be processed with a form of cutting fluid. Overrides Silk Touch where applicable. ritual.BloodMagic.greenGroveRitual.corrosive.info=(Corrosive) Entities within range are attacked by nearby plants, leeching away their life. +ritual.BloodMagic.greenGroveRitual.default.info=(Raw) Increases the speed of all of the ritual operations depending on the total Will in the Aura. +ritual.BloodMagic.greenGroveRitual.steadfast.info=(Steadfast) Seeds are replanted and blocks are hydrated within the Hydration range. ritual.BloodMagic.fullStomachRitual.info=Takes food from the linked chest and fills the player's saturation with it. ritual.BloodMagic.interdictionRitual.info=Pushes all mobs within its area away from the master ritual stone. @@ -516,6 +518,7 @@ ritual.BloodMagic.lavaRitual.lavaRange.info=(Lava) The area that the ritual will ritual.BloodMagic.lavaRitual.fireFuse.info=(Vengeful) Entities in this range are afflicted by Fire Fuse. ritual.BloodMagic.greenGroveRitual.growing.info=(Growth) The area that the ritual will grow plants in. ritual.BloodMagic.greenGroveRitual.leech.info=(Corrosive) Entities in this area have their life drained to grow nearby crops. +ritual.BloodMagic.greenGroveRitual.hydrate.info=(Steadfast) Blocks within this range are rehydrated into farmland, and seeds within the area are planted nearby. ritual.BloodMagic.jumpRitual.jumpRange.info=(Jumping) Entities in this range will be launched in the air. ritual.BloodMagic.wellOfSufferingRitual.altar.info=(Altar) This range defines the area that the ritual searches for the blood altar. Changing this will either expand or limit the range to a certain region. ritual.BloodMagic.wellOfSufferingRitual.damage.info=(Damage) This defines where the ritual will damage a mob. All mobs inside of this range (except for players) will receive damage over time.