BloodMagic/src/main/java/WayofTime/bloodmagic/ritual/RitualLava.java

320 lines
12 KiB
Java

package WayofTime.bloodmagic.ritual;
import java.util.ArrayList;
import java.util.List;
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.init.MobEffects;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import WayofTime.bloodmagic.api.BloodMagicAPI;
import WayofTime.bloodmagic.api.Constants;
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.saving.SoulNetwork;
import WayofTime.bloodmagic.api.soul.DemonWillHolder;
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 RitualLava extends Ritual
{
public static final String LAVA_RANGE = "lavaRange";
public static final String FIRE_FUSE_RANGE = "fireFuse";
public static final String FIRE_RESIST_RANGE = "fireResist";
public static final String FIRE_DAMAGE_RANGE = "fireDamage";
public static final double vengefulWillDrain = 1;
public static final double steadfastWillDrain = 0.5;
public static final double corrosiveWillDrain = 0.2;
public int timer = 0;
public static final int corrosiveRefreshTime = 20;
public RitualLava()
{
super("ritualLava", 0, 10000, "ritual." + Constants.Mod.MODID + ".lavaRitual");
addBlockRange(LAVA_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 1, 0), 1));
addBlockRange(FIRE_FUSE_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-2, -2, -2), 5));
addBlockRange(FIRE_RESIST_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 0, 0), 1));
addBlockRange(FIRE_DAMAGE_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 0, 0), 1));
setMaximumVolumeAndDistanceOfRange(LAVA_RANGE, 9, 3, 3);
setMaximumVolumeAndDistanceOfRange(FIRE_FUSE_RANGE, 0, 10, 10);
setMaximumVolumeAndDistanceOfRange(FIRE_RESIST_RANGE, 0, 10, 10);
setMaximumVolumeAndDistanceOfRange(FIRE_DAMAGE_RANGE, 0, 10, 10);
}
@Override
public void performRitual(IMasterRitualStone masterRitualStone)
{
timer++;
World world = masterRitualStone.getWorldObj();
SoulNetwork network = NetworkHelper.getSoulNetwork(masterRitualStone.getOwner());
int currentEssence = network.getCurrentEssence();
int lpDrain = 0;
if (currentEssence < getRefreshCost())
{
network.causeNausea();
return;
}
BlockPos pos = masterRitualStone.getBlockPos();
List<EnumDemonWillType> willConfig = masterRitualStone.getActiveWillConfig();
double rawWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.DEFAULT, willConfig);
double rawDrained = 0;
DemonWillHolder holder = WorldDemonWillHandler.getWillHolder(world, pos);
AreaDescriptor lavaRange = getBlockRange(LAVA_RANGE);
int maxLavaVolume = getMaxVolumeForRange(LAVA_RANGE, willConfig, holder);
if (!lavaRange.isWithinRange(getMaxVerticalRadiusForRange(LAVA_RANGE, willConfig, holder), getMaxHorizontalRadiusForRange(LAVA_RANGE, willConfig, holder)) || (maxLavaVolume != 0 && lavaRange.getVolume() > maxLavaVolume))
{
return;
}
for (BlockPos newPos : lavaRange.getContainedPositions(pos))
{
IBlockState state = world.getBlockState(newPos);
if (world.isAirBlock(newPos) || Utils.isFlowingLiquid(world, newPos, state))
{
int lpCost = getLPCostForRawWill(rawWill);
if (currentEssence < lpCost)
{
break;
}
world.setBlockState(newPos, Blocks.FLOWING_LAVA.getDefaultState());
currentEssence -= lpCost;
lpDrain += lpCost;
if (rawWill > 0)
{
double drain = getWillCostForRawWill(rawWill);
rawWill -= drain;
rawDrained += drain;
}
}
}
double vengefulWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.VENGEFUL, willConfig);
double steadfastWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.STEADFAST, willConfig);
double corrosiveWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.CORROSIVE, willConfig);
if (vengefulWill >= vengefulWillDrain)
{
double vengefulDrained = 0;
AreaDescriptor fuseRange = getBlockRange(FIRE_FUSE_RANGE);
AxisAlignedBB fuseArea = fuseRange.getAABB(pos);
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, fuseArea);
for (EntityLivingBase entity : entities)
{
if (vengefulWill < vengefulWillDrain)
{
break;
}
if (entity instanceof EntityPlayer)
{
continue;
}
if (!entity.isPotionActive(ModPotions.fireFuse))
{
entity.addPotionEffect(new PotionEffect(ModPotions.fireFuse, 100, 0));
vengefulDrained += vengefulWillDrain;
vengefulWill -= vengefulWillDrain;
}
}
if (vengefulDrained > 0)
{
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.VENGEFUL, vengefulDrained, true);
}
}
if (steadfastWill >= steadfastWillDrain)
{
double steadfastDrained = 0;
AreaDescriptor resistRange = getBlockRange(FIRE_RESIST_RANGE);
int duration = getFireResistForWill(steadfastWill);
AxisAlignedBB resistArea = resistRange.getAABB(pos);
List<EntityPlayer> entities = world.getEntitiesWithinAABB(EntityPlayer.class, resistArea);
for (EntityPlayer entity : entities)
{
if (steadfastWill < steadfastWillDrain)
{
break;
}
if (!entity.isPotionActive(MobEffects.FIRE_RESISTANCE) || (entity.getActivePotionEffect(MobEffects.FIRE_RESISTANCE).getDuration() < 2))
{
entity.addPotionEffect(new PotionEffect(MobEffects.FIRE_RESISTANCE, 100, 0));
steadfastDrained += steadfastWillDrain;
steadfastWill -= steadfastWillDrain;
}
}
if (steadfastDrained > 0)
{
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.STEADFAST, steadfastDrained, true);
}
}
if (timer % corrosiveRefreshTime == 0 && corrosiveWill >= corrosiveWillDrain)
{
double corrosiveDrained = 0;
AreaDescriptor resistRange = getBlockRange(FIRE_DAMAGE_RANGE);
float damage = getCorrosiveDamageForWill(corrosiveWill);
AxisAlignedBB damageArea = resistRange.getAABB(pos);
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, damageArea);
for (EntityLivingBase entity : entities)
{
if (corrosiveWill < corrosiveWillDrain)
{
break;
}
if (!entity.isDead && entity.hurtTime <= 0 && Utils.isImmuneToFireDamage(entity))
{
if (entity.attackEntityFrom(BloodMagicAPI.getDamageSource(), damage))
{
corrosiveDrained += corrosiveWillDrain;
corrosiveWill -= corrosiveWillDrain;
}
}
}
if (corrosiveDrained > 0)
{
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.CORROSIVE, corrosiveDrained, true);
}
}
if (rawDrained > 0)
{
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.DEFAULT, rawDrained, true);
}
network.syphon(lpDrain);
}
@Override
public int getRefreshTime()
{
return 1;
}
@Override
public int getRefreshCost()
{
return 500;
}
@Override
public ITextComponent[] provideInformationOfRitualToPlayer(EntityPlayer player)
{
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"), new TextComponentTranslation(this.getUnlocalizedName() + ".destructive.info"), new TextComponentTranslation(this.getUnlocalizedName() + ".vengeful.info") };
}
@Override
public ArrayList<RitualComponent> getComponents()
{
ArrayList<RitualComponent> components = new ArrayList<RitualComponent>();
this.addParallelRunes(components, 1, 0, EnumRuneType.FIRE);
return components;
}
@Override
public Ritual getNewCopy()
{
return new RitualLava();
}
@Override
public int getMaxVolumeForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
{
if (LAVA_RANGE.equals(range) && activeTypes.contains(EnumDemonWillType.DESTRUCTIVE))
{
double destructiveWill = holder.getWill(EnumDemonWillType.DESTRUCTIVE);
if (destructiveWill > 0)
{
return 9 + (int) Math.pow(destructiveWill / 10, 1.5);
}
}
return volumeRangeMap.get(range);
}
@Override
public int getMaxVerticalRadiusForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
{
if (LAVA_RANGE.equals(range) && activeTypes.contains(EnumDemonWillType.DESTRUCTIVE))
{
double destructiveWill = holder.getWill(EnumDemonWillType.DESTRUCTIVE);
if (destructiveWill > 0)
{
return (int) (3 + destructiveWill / 10d);
}
}
return verticalRangeMap.get(range);
}
@Override
public int getMaxHorizontalRadiusForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
{
if (LAVA_RANGE.equals(range) && activeTypes.contains(EnumDemonWillType.DESTRUCTIVE))
{
double destructiveWill = holder.getWill(EnumDemonWillType.DESTRUCTIVE);
if (destructiveWill > 0)
{
return (int) (3 + destructiveWill / 10d);
}
}
return horizontalRangeMap.get(range);
}
public int getFireResistForWill(double steadfastWill)
{
return (int) (200 + steadfastWill * 3);
}
public float getCorrosiveDamageForWill(double corrosiveWill)
{
return (float) (1 + corrosiveWill * 0.05);
}
public int getLPCostForRawWill(double raw)
{
return Math.max((int) (500 - raw), 0);
}
public double getWillCostForRawWill(double raw)
{
return Math.min(1, raw / 500);
}
}