Additional Rituals
Added Ritual of Magnetism and Ritual of Crushing.
This commit is contained in:
parent
6e3f1b3a4e
commit
4ac0f31124
9 changed files with 1362 additions and 6 deletions
|
@ -6,11 +6,13 @@ import net.minecraftforge.registries.IForgeRegistry;
|
|||
|
||||
public class BloodMagicPotions
|
||||
{
|
||||
public static final Effect soulSnare = new PotionSoulSnare();
|
||||
public static final Effect SOUL_SNARE = new PotionSoulSnare();
|
||||
public static final Effect FIRE_FUSE = new PotionFireFuse();
|
||||
|
||||
public static void registerPotions(RegistryEvent.Register<Effect> evt)
|
||||
{
|
||||
IForgeRegistry<Effect> reg = evt.getRegistry();
|
||||
reg.register(soulSnare.setRegistryName("soulsnare"));
|
||||
reg.register(SOUL_SNARE.setRegistryName("soulsnare"));
|
||||
reg.register(FIRE_FUSE.setRegistryName("firefuse"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package wayoftime.bloodmagic.potion;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.potion.EffectType;
|
||||
import net.minecraft.world.Explosion;
|
||||
|
||||
public class PotionFireFuse extends PotionBloodMagic
|
||||
{
|
||||
public PotionFireFuse()
|
||||
{
|
||||
super(EffectType.HARMFUL, 0xFF0000FF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performEffect(LivingEntity entity, int amplifier)
|
||||
{
|
||||
if (entity.world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Random random = entity.world.rand;
|
||||
entity.getEntityWorld().addParticle(ParticleTypes.FLAME, entity.getPosX()
|
||||
+ random.nextDouble() * 0.3, entity.getPosY()
|
||||
+ random.nextDouble() * 0.3, entity.getPosZ() + random.nextDouble() * 0.3, 0, 0.06d, 0);
|
||||
|
||||
int radius = amplifier + 1;
|
||||
|
||||
if (entity.getActivePotionEffect(BloodMagicPotions.FIRE_FUSE).getDuration() <= 3)
|
||||
{
|
||||
Explosion.Mode explosion$mode = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(entity.world, entity)
|
||||
? Explosion.Mode.DESTROY
|
||||
: Explosion.Mode.NONE;
|
||||
entity.getEntityWorld().createExplosion(null, entity.getPosX(), entity.getPosY(), entity.getPosZ(), radius, false, explosion$mode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,360 @@
|
|||
package wayoftime.bloodmagic.ritual.types;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.LootContext;
|
||||
import net.minecraft.loot.LootParameters;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.common.block.BlockMasterRitualStone;
|
||||
import wayoftime.bloodmagic.demonaura.WorldDemonWillHandler;
|
||||
import wayoftime.bloodmagic.ritual.AreaDescriptor;
|
||||
import wayoftime.bloodmagic.ritual.EnumRuneType;
|
||||
import wayoftime.bloodmagic.ritual.IMasterRitualStone;
|
||||
import wayoftime.bloodmagic.ritual.IRitualStone;
|
||||
import wayoftime.bloodmagic.ritual.Ritual;
|
||||
import wayoftime.bloodmagic.ritual.RitualComponent;
|
||||
import wayoftime.bloodmagic.ritual.RitualRegister;
|
||||
import wayoftime.bloodmagic.util.Utils;
|
||||
import wayoftime.bloodmagic.will.EnumDemonWillType;
|
||||
|
||||
@RitualRegister("crushing")
|
||||
public class RitualCrushing extends Ritual
|
||||
{
|
||||
public static final String CRUSHING_RANGE = "crushingRange";
|
||||
public static final String CHEST_RANGE = "chest";
|
||||
|
||||
public static double rawWillDrain = 0.05;
|
||||
public static double steadfastWillDrain = 0.2;
|
||||
public static double destructiveWillDrain = 0.2;
|
||||
public static double vengefulWillDrain = 0.2;
|
||||
|
||||
public static Map<ItemStack, Integer> cuttingFluidLPMap = new HashMap<>();
|
||||
public static Map<ItemStack, Double> cuttingFluidWillMap = new HashMap<>();
|
||||
public static int defaultRefreshTime = 40;
|
||||
private FakePlayer fakePlayer;
|
||||
public int refreshTime = 40;
|
||||
|
||||
private static final ItemStack mockPick = new ItemStack(Items.DIAMOND_PICKAXE, 1);
|
||||
static
|
||||
{
|
||||
mockPick.addEnchantment(Enchantments.SILK_TOUCH, 1);
|
||||
}
|
||||
|
||||
public RitualCrushing()
|
||||
{
|
||||
super("ritualCrushing", 0, 5000, "ritual." + BloodMagic.MODID + ".crushingRitual");
|
||||
addBlockRange(CRUSHING_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-1, -3, -1), 3));
|
||||
addBlockRange(CHEST_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 1, 0), 1));
|
||||
|
||||
setMaximumVolumeAndDistanceOfRange(CRUSHING_RANGE, 50, 10, 10);
|
||||
setMaximumVolumeAndDistanceOfRange(CHEST_RANGE, 1, 3, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRitual(IMasterRitualStone masterRitualStone)
|
||||
{
|
||||
World world = masterRitualStone.getWorldObj();
|
||||
if (world.isRemote)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int currentEssence = masterRitualStone.getOwnerNetwork().getCurrentEssence();
|
||||
|
||||
if (currentEssence < getRefreshCost())
|
||||
{
|
||||
masterRitualStone.getOwnerNetwork().causeNausea();
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos pos = masterRitualStone.getBlockPos();
|
||||
AreaDescriptor chestRange = masterRitualStone.getBlockRange(CHEST_RANGE);
|
||||
TileEntity tile = world.getTileEntity(chestRange.getContainedPositions(pos).get(0));
|
||||
|
||||
if (tile != null && Utils.getNumberOfFreeSlots(tile, Direction.DOWN) < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<EnumDemonWillType> willConfig = masterRitualStone.getActiveWillConfig();
|
||||
|
||||
double rawWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.DEFAULT, willConfig);
|
||||
double steadfastWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.STEADFAST, willConfig);
|
||||
double corrosiveWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.CORROSIVE, willConfig);
|
||||
double destructiveWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.DESTRUCTIVE, willConfig);
|
||||
double vengefulWill = this.getWillRespectingConfig(world, pos, EnumDemonWillType.VENGEFUL, willConfig);
|
||||
|
||||
refreshTime = getRefreshTimeForRawWill(rawWill);
|
||||
|
||||
boolean consumeRawWill = rawWill >= rawWillDrain && refreshTime != defaultRefreshTime;
|
||||
|
||||
boolean isSilkTouch = steadfastWill >= steadfastWillDrain;
|
||||
boolean useCuttingFluid = corrosiveWill > 0;
|
||||
|
||||
int fortune = destructiveWill > 0 ? 3 : 0;
|
||||
|
||||
AreaDescriptor crushingRange = masterRitualStone.getBlockRange(CRUSHING_RANGE);
|
||||
boolean hasOperated = false;
|
||||
|
||||
double rawDrain = 0;
|
||||
|
||||
for (BlockPos newPos : crushingRange.getContainedPositions(pos))
|
||||
{
|
||||
if (world.isAirBlock(newPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockState state = world.getBlockState(newPos);
|
||||
Block block = state.getBlock();
|
||||
|
||||
if (block instanceof BlockMasterRitualStone || block instanceof IRitualStone
|
||||
|| state.getBlockHardness(world, newPos) == -1.0F || Utils.isBlockLiquid(state))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean isBlockClaimed = false;
|
||||
// if (useCuttingFluid)
|
||||
// {
|
||||
// ItemStack checkStack = block.getItem(world, newPos, state);
|
||||
// if (checkStack.isEmpty())
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// ItemStack copyStack = checkStack.copy();
|
||||
//
|
||||
// for (ICrushingHandler handler : CrushingRegistry.getCrushingHandlerList())
|
||||
// {
|
||||
// int lpDrain = handler.getLpDrain();
|
||||
// double willDrain = handler.getWillDrain();
|
||||
//
|
||||
// if (corrosiveWill < willDrain || currentEssence < lpDrain + getRefreshCost())
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// ItemStack result = handler.getRecipeOutput(copyStack, world, pos);
|
||||
//
|
||||
// if (result.isEmpty())
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (tile != null)
|
||||
// {
|
||||
// result = Utils.insertStackIntoTile(result, tile, Direction.DOWN);
|
||||
// if (!result.isEmpty())
|
||||
// {
|
||||
// Utils.spawnStackAtBlock(world, pos, Direction.UP, result);
|
||||
// }
|
||||
// } else
|
||||
// {
|
||||
// Utils.spawnStackAtBlock(world, pos, Direction.UP, result);
|
||||
// }
|
||||
//
|
||||
// WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.CORROSIVE, willDrain, true);
|
||||
// corrosiveWill -= willDrain;
|
||||
//
|
||||
// masterRitualStone.getOwnerNetwork().syphon(masterRitualStone.ticket(lpDrain));
|
||||
// currentEssence -= lpDrain;
|
||||
//
|
||||
// isBlockClaimed = true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
Blocks d;
|
||||
if (!isBlockClaimed && isSilkTouch)
|
||||
{
|
||||
LootContext.Builder lootBuilder = new LootContext.Builder((ServerWorld) world);
|
||||
Vector3d blockCenter = new Vector3d(newPos.getX() + 0.5, newPos.getY() + 0.5, newPos.getZ() + 0.5);
|
||||
List<ItemStack> silkDrops = state.getDrops(lootBuilder.withParameter(LootParameters.field_237457_g_, blockCenter).withParameter(LootParameters.TOOL, mockPick));
|
||||
|
||||
for (ItemStack item : silkDrops)
|
||||
{
|
||||
ItemStack copyStack = item.copy();
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
copyStack = Utils.insertStackIntoTile(copyStack, tile, Direction.DOWN);
|
||||
} else
|
||||
{
|
||||
Utils.spawnStackAtBlock(world, pos, Direction.UP, copyStack);
|
||||
continue;
|
||||
}
|
||||
if (!copyStack.isEmpty())
|
||||
{
|
||||
Utils.spawnStackAtBlock(world, pos, Direction.UP, copyStack);
|
||||
}
|
||||
}
|
||||
|
||||
if (steadfastWill >= steadfastWillDrain)
|
||||
{
|
||||
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.STEADFAST, steadfastWillDrain, true);
|
||||
steadfastWill -= steadfastWillDrain;
|
||||
} else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (!isBlockClaimed)
|
||||
{
|
||||
if (fortune > 0 && destructiveWill < destructiveWillDrain)
|
||||
{
|
||||
fortune = 0;
|
||||
}
|
||||
|
||||
ItemStack mockFortunePick = new ItemStack(Items.DIAMOND_PICKAXE, 1);
|
||||
mockFortunePick.addEnchantment(Enchantments.FORTUNE, fortune);
|
||||
|
||||
LootContext.Builder lootBuilder = new LootContext.Builder((ServerWorld) world);
|
||||
Vector3d blockCenter = new Vector3d(newPos.getX() + 0.5, newPos.getY() + 0.5, newPos.getZ() + 0.5);
|
||||
List<ItemStack> stackList = state.getDrops(lootBuilder.withParameter(LootParameters.field_237457_g_, blockCenter).withParameter(LootParameters.TOOL, mockFortunePick));
|
||||
// List<ItemStack> stackList = Block.getDrops(state, world, newPos, world.getTileEntity(newPos));
|
||||
|
||||
// List<ItemStack> stackList = block.getDrops(world, newPos, state, fortune);
|
||||
|
||||
for (ItemStack item : stackList)
|
||||
{
|
||||
ItemStack copyStack = item.copy();
|
||||
|
||||
if (tile != null)
|
||||
{
|
||||
copyStack = Utils.insertStackIntoTile(copyStack, tile, Direction.DOWN);
|
||||
} else
|
||||
{
|
||||
Utils.spawnStackAtBlock(world, pos, Direction.UP, copyStack);
|
||||
continue;
|
||||
}
|
||||
if (!copyStack.isEmpty())
|
||||
{
|
||||
Utils.spawnStackAtBlock(world, pos, Direction.UP, copyStack);
|
||||
}
|
||||
}
|
||||
|
||||
if (fortune > 0)
|
||||
{
|
||||
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.DESTRUCTIVE, destructiveWillDrain, true);
|
||||
destructiveWill -= destructiveWillDrain;
|
||||
}
|
||||
}
|
||||
|
||||
world.destroyBlock(newPos, false);
|
||||
masterRitualStone.getOwnerNetwork().syphon(masterRitualStone.ticket(getRefreshCost()));
|
||||
hasOperated = true;
|
||||
|
||||
if (consumeRawWill)
|
||||
{
|
||||
rawDrain += rawWillDrain;
|
||||
rawWill -= rawWillDrain;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// if (hasOperated && tile != null && vengefulWill >= vengefulWillDrain)
|
||||
// {
|
||||
// Pair<ItemStack, Boolean> pair = CompressionRegistry.compressInventory(tile, world);
|
||||
// if (pair.getRight())
|
||||
// {
|
||||
// ItemStack returned = pair.getLeft();
|
||||
// if (returned != null)
|
||||
// {
|
||||
// Utils.spawnStackAtBlock(world, pos, Direction.UP, returned);
|
||||
// }
|
||||
//
|
||||
// WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.VENGEFUL, vengefulWillDrain, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (rawDrain > 0)
|
||||
{
|
||||
WorldDemonWillHandler.drainWill(world, pos, EnumDemonWillType.DEFAULT, rawDrain, true);
|
||||
}
|
||||
}
|
||||
|
||||
public int getRefreshTimeForRawWill(double rawWill)
|
||||
{
|
||||
if (rawWill >= rawWillDrain)
|
||||
{
|
||||
return Math.max(1, (int) (40 - rawWill / 5));
|
||||
}
|
||||
|
||||
return defaultRefreshTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshTime()
|
||||
{
|
||||
return refreshTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshCost()
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gatherComponents(Consumer<RitualComponent> components)
|
||||
{
|
||||
addParallelRunes(components, 1, 0, EnumRuneType.EARTH);
|
||||
addParallelRunes(components, 2, 0, EnumRuneType.FIRE);
|
||||
addCornerRunes(components, 2, 0, EnumRuneType.DUSK);
|
||||
addParallelRunes(components, 2, 1, EnumRuneType.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent[] provideInformationOfRitualToPlayer(PlayerEntity player)
|
||||
{
|
||||
return new ITextComponent[]
|
||||
{ new TranslationTextComponent(this.getTranslationKey() + ".info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".default.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".corrosive.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".steadfast.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".destructive.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".vengeful.info") };
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ritual getNewCopy()
|
||||
{
|
||||
return new RitualCrushing();
|
||||
}
|
||||
|
||||
public static void registerCuttingFluid(ItemStack stack, int lpDrain, double willDrain)
|
||||
{
|
||||
cuttingFluidLPMap.put(stack, lpDrain);
|
||||
cuttingFluidWillMap.put(stack, willDrain);
|
||||
}
|
||||
|
||||
private FakePlayer getFakePlayer(ServerWorld world)
|
||||
{
|
||||
return fakePlayer == null
|
||||
? fakePlayer = FakePlayerFactory.get(world, new GameProfile(null, BloodMagic.MODID + "_ritual_crushing"))
|
||||
: fakePlayer;
|
||||
}
|
||||
}
|
362
src/main/java/wayoftime/bloodmagic/ritual/types/RitualLava.java
Normal file
362
src/main/java/wayoftime/bloodmagic/ritual/types/RitualLava.java
Normal file
|
@ -0,0 +1,362 @@
|
|||
package wayoftime.bloodmagic.ritual.types;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.demonaura.WorldDemonWillHandler;
|
||||
import wayoftime.bloodmagic.potion.BloodMagicPotions;
|
||||
import wayoftime.bloodmagic.ritual.AreaDescriptor;
|
||||
import wayoftime.bloodmagic.ritual.EnumRuneType;
|
||||
import wayoftime.bloodmagic.ritual.IMasterRitualStone;
|
||||
import wayoftime.bloodmagic.ritual.Ritual;
|
||||
import wayoftime.bloodmagic.ritual.RitualComponent;
|
||||
import wayoftime.bloodmagic.ritual.RitualRegister;
|
||||
import wayoftime.bloodmagic.util.DamageSourceBloodMagic;
|
||||
import wayoftime.bloodmagic.util.Utils;
|
||||
import wayoftime.bloodmagic.will.DemonWillHolder;
|
||||
import wayoftime.bloodmagic.will.EnumDemonWillType;
|
||||
|
||||
@RitualRegister("lava")
|
||||
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 String LAVA_TANK_RANGE = "lavaTank";
|
||||
|
||||
public static final double vengefulWillDrain = 1;
|
||||
public static final double steadfastWillDrain = 0.5;
|
||||
public static final double corrosiveWillDrain = 0.2;
|
||||
public static final int corrosiveRefreshTime = 20;
|
||||
public int timer = 0;
|
||||
|
||||
public RitualLava()
|
||||
{
|
||||
super("ritualLava", 0, 10000, "ritual." + BloodMagic.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));
|
||||
addBlockRange(LAVA_TANK_RANGE, new AreaDescriptor.Rectangle(new BlockPos(0, 1, 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);
|
||||
setMaximumVolumeAndDistanceOfRange(LAVA_TANK_RANGE, 1, 10, 10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRitual(IMasterRitualStone masterRitualStone)
|
||||
{
|
||||
timer++;
|
||||
World world = masterRitualStone.getWorldObj();
|
||||
int currentEssence = masterRitualStone.getOwnerNetwork().getCurrentEssence();
|
||||
int lpDrain = 0;
|
||||
|
||||
if (currentEssence < getRefreshCost())
|
||||
{
|
||||
masterRitualStone.getOwnerNetwork().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 = masterRitualStone.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))
|
||||
{
|
||||
BlockState 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.LAVA.getDefaultState());
|
||||
currentEssence -= lpCost;
|
||||
lpDrain += lpCost;
|
||||
if (rawWill > 0)
|
||||
{
|
||||
double drain = getWillCostForRawWill(rawWill);
|
||||
rawWill -= drain;
|
||||
rawDrained += drain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rawWill > 0)
|
||||
{
|
||||
AreaDescriptor chestRange = masterRitualStone.getBlockRange(LAVA_TANK_RANGE);
|
||||
TileEntity tile = world.getTileEntity(chestRange.getContainedPositions(pos).get(0));
|
||||
double drain = getWillCostForRawWill(rawWill);
|
||||
int lpCost = getLPCostForRawWill(rawWill);
|
||||
|
||||
if (rawWill >= drain && currentEssence >= lpCost)
|
||||
{
|
||||
if (tile != null)
|
||||
{
|
||||
LazyOptional<IFluidHandler> capability = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, null);
|
||||
if (capability.isPresent())
|
||||
{
|
||||
IFluidHandler handler = capability.resolve().get();
|
||||
double filled = handler.fill(new FluidStack(Fluids.LAVA, 1000), FluidAction.EXECUTE);
|
||||
|
||||
double ratio = filled / 1000;
|
||||
|
||||
rawWill -= drain * ratio;
|
||||
rawDrained += drain * ratio;
|
||||
|
||||
currentEssence -= Math.ceil(lpCost * ratio);
|
||||
lpDrain += Math.ceil(lpCost * ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = masterRitualStone.getBlockRange(FIRE_FUSE_RANGE);
|
||||
|
||||
AxisAlignedBB fuseArea = fuseRange.getAABB(pos);
|
||||
List<LivingEntity> entities = world.getEntitiesWithinAABB(LivingEntity.class, fuseArea);
|
||||
|
||||
for (LivingEntity entity : entities)
|
||||
{
|
||||
if (vengefulWill < vengefulWillDrain)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (entity instanceof PlayerEntity)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entity.isPotionActive(BloodMagicPotions.FIRE_FUSE))
|
||||
{
|
||||
entity.addPotionEffect(new EffectInstance(BloodMagicPotions.FIRE_FUSE, 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 = masterRitualStone.getBlockRange(FIRE_RESIST_RANGE);
|
||||
|
||||
int duration = getFireResistForWill(steadfastWill);
|
||||
|
||||
AxisAlignedBB resistArea = resistRange.getAABB(pos);
|
||||
List<PlayerEntity> entities = world.getEntitiesWithinAABB(PlayerEntity.class, resistArea);
|
||||
|
||||
for (PlayerEntity entity : entities)
|
||||
{
|
||||
if (steadfastWill < steadfastWillDrain)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!entity.isPotionActive(Effects.FIRE_RESISTANCE)
|
||||
|| (entity.getActivePotionEffect(Effects.FIRE_RESISTANCE).getDuration() < 2))
|
||||
{
|
||||
entity.addPotionEffect(new EffectInstance(Effects.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 = masterRitualStone.getBlockRange(FIRE_DAMAGE_RANGE);
|
||||
|
||||
float damage = getCorrosiveDamageForWill(corrosiveWill);
|
||||
|
||||
AxisAlignedBB damageArea = resistRange.getAABB(pos);
|
||||
List<LivingEntity> entities = world.getEntitiesWithinAABB(LivingEntity.class, damageArea);
|
||||
|
||||
for (LivingEntity entity : entities)
|
||||
{
|
||||
if (corrosiveWill < corrosiveWillDrain)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!entity.isAlive() && entity.hurtTime <= 0 && Utils.isImmuneToFireDamage(entity))
|
||||
{
|
||||
if (entity.attackEntityFrom(DamageSourceBloodMagic.INSTANCE, 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);
|
||||
}
|
||||
|
||||
masterRitualStone.getOwnerNetwork().syphon(masterRitualStone.ticket(lpDrain));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshTime()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshCost()
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent[] provideInformationOfRitualToPlayer(PlayerEntity player)
|
||||
{
|
||||
return new ITextComponent[]
|
||||
{ new TranslationTextComponent(this.getTranslationKey() + ".info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".default.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".corrosive.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".steadfast.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".destructive.info"),
|
||||
new TranslationTextComponent(this.getTranslationKey() + ".vengeful.info") };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gatherComponents(Consumer<RitualComponent> components)
|
||||
{
|
||||
addParallelRunes(components, 1, 0, EnumRuneType.FIRE);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package wayoftime.bloodmagic.ritual.types;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.ritual.AreaDescriptor;
|
||||
import wayoftime.bloodmagic.ritual.EnumRuneType;
|
||||
import wayoftime.bloodmagic.ritual.IMasterRitualStone;
|
||||
import wayoftime.bloodmagic.ritual.Ritual;
|
||||
import wayoftime.bloodmagic.ritual.RitualComponent;
|
||||
import wayoftime.bloodmagic.ritual.RitualRegister;
|
||||
import wayoftime.bloodmagic.util.Utils;
|
||||
|
||||
@RitualRegister("magnetism")
|
||||
public class RitualMagnetic extends Ritual
|
||||
{
|
||||
public static final String PLACEMENT_RANGE = "placementRange";
|
||||
// public static final String SEARCH_RANGE = "searchRange";
|
||||
public BlockPos lastPos; // An offset
|
||||
private FakePlayer fakePlayer;
|
||||
|
||||
public RitualMagnetic()
|
||||
{
|
||||
super("ritualMagnetic", 0, 5000, "ritual." + BloodMagic.MODID + ".magneticRitual");
|
||||
addBlockRange(PLACEMENT_RANGE, new AreaDescriptor.Rectangle(new BlockPos(-1, 1, -1), 3));
|
||||
setMaximumVolumeAndDistanceOfRange(PLACEMENT_RANGE, 50, 4, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRitual(IMasterRitualStone masterRitualStone)
|
||||
{
|
||||
World world = masterRitualStone.getWorldObj();
|
||||
Vector3d MRSpos = new Vector3d(masterRitualStone.getBlockPos().getX(), masterRitualStone.getBlockPos().getY(), masterRitualStone.getBlockPos().getZ());
|
||||
int currentEssence = masterRitualStone.getOwnerNetwork().getCurrentEssence();
|
||||
|
||||
if (currentEssence < getRefreshCost())
|
||||
{
|
||||
masterRitualStone.getOwnerNetwork().causeNausea();
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos pos = masterRitualStone.getBlockPos();
|
||||
|
||||
AreaDescriptor placementRange = masterRitualStone.getBlockRange(PLACEMENT_RANGE);
|
||||
|
||||
BlockPos replacement = pos;
|
||||
boolean replace = false;
|
||||
|
||||
for (BlockPos offset : placementRange.getContainedPositions(pos))
|
||||
{
|
||||
if (world.isAirBlock(offset))
|
||||
{
|
||||
replacement = offset;
|
||||
replace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlockState downState = world.getBlockState(pos.down());
|
||||
int radius = getRadius(downState.getBlock());
|
||||
|
||||
if (replace)
|
||||
{
|
||||
int j = -1;
|
||||
int i = -radius;
|
||||
int k = -radius;
|
||||
|
||||
if (lastPos != null)
|
||||
{
|
||||
j = lastPos.getY();
|
||||
i = Math.min(radius, Math.max(-radius, lastPos.getX()));
|
||||
k = Math.min(radius, Math.max(-radius, lastPos.getZ()));
|
||||
}
|
||||
|
||||
if (j + pos.getY() >= 0)
|
||||
{
|
||||
while (i <= radius)
|
||||
{
|
||||
while (k <= radius)
|
||||
{
|
||||
BlockPos newPos = pos.add(i, j, k);
|
||||
Vector3d newPosVector = new Vector3d(newPos.getX(), newPos.getY(), newPos.getZ());
|
||||
BlockState state = world.getBlockState(newPos);
|
||||
// RayTraceResult fakeRayTrace = world.rayTraceBlocks(MRSpos, newPosVector, false);
|
||||
// ItemStack checkStack = state.getBlock().getPickBlock(state, fakeRayTrace, world, newPos, getFakePlayer((ServerWorld) world));
|
||||
ItemStack checkStack = new ItemStack(state.getBlock());
|
||||
if (isBlockOre(checkStack))
|
||||
{
|
||||
Utils.swapLocations(world, newPos, world, replacement);
|
||||
masterRitualStone.getOwnerNetwork().syphon(masterRitualStone.ticket(getRefreshCost()));
|
||||
k++;
|
||||
this.lastPos = new BlockPos(i, j, k);
|
||||
return;
|
||||
} else
|
||||
{
|
||||
k++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
k = -radius;
|
||||
}
|
||||
j--;
|
||||
i = -radius;
|
||||
this.lastPos = new BlockPos(i, j, k);
|
||||
return;
|
||||
}
|
||||
|
||||
j = -1;
|
||||
this.lastPos = new BlockPos(i, j, k);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getRadius(Block block)
|
||||
{
|
||||
if (block == Blocks.IRON_BLOCK)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (block == Blocks.GOLD_BLOCK)
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
if (block == Blocks.DIAMOND_BLOCK)
|
||||
{
|
||||
return 31;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshTime()
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRefreshCost()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gatherComponents(Consumer<RitualComponent> components)
|
||||
{
|
||||
addCornerRunes(components, 1, 0, EnumRuneType.EARTH);
|
||||
addParallelRunes(components, 2, 1, EnumRuneType.EARTH);
|
||||
addCornerRunes(components, 2, 1, EnumRuneType.AIR);
|
||||
addParallelRunes(components, 2, 2, EnumRuneType.FIRE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ritual getNewCopy()
|
||||
{
|
||||
return new RitualMagnetic();
|
||||
}
|
||||
|
||||
private FakePlayer getFakePlayer(ServerWorld world)
|
||||
{
|
||||
return fakePlayer == null
|
||||
? fakePlayer = FakePlayerFactory.get(world, new GameProfile(null, BloodMagic.MODID + "_ritual_magnetic"))
|
||||
: fakePlayer;
|
||||
}
|
||||
|
||||
public static boolean isBlockOre(ItemStack stack)
|
||||
{
|
||||
if (stack.isEmpty())
|
||||
return false;
|
||||
|
||||
return stack.getItem().isIn(Tags.Items.ORES);
|
||||
|
||||
// for(ResourceLocation rl : stack.getItem().getTags())
|
||||
// {
|
||||
// rl.getPath()
|
||||
// }
|
||||
|
||||
// for (int id : OreDictionary.getOreIDs(stack))
|
||||
// {
|
||||
// String oreName = OreDictionary.getOreName(id);
|
||||
// if (oreName.contains("ore"))
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ public class ClientHandler
|
|||
public static ResourceLocation ritualStoneEarth = BloodMagic.rl("block/earthritualstone");;
|
||||
public static ResourceLocation ritualStoneAir = BloodMagic.rl("block/airritualstone");;
|
||||
public static ResourceLocation ritualStoneDawn = BloodMagic.rl("block/dawnritualstone");;
|
||||
public static ResourceLocation ritualStoneDusk = BloodMagic.rl("block/lightritualstone");;
|
||||
public static ResourceLocation ritualStoneDusk = BloodMagic.rl("block/duskritualstone");;
|
||||
public static TextureAtlasSprite blankBloodRune;
|
||||
public static TextureAtlasSprite stoneBrick;
|
||||
public static TextureAtlasSprite glowstone;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue