Additional Rituals
Added Ritual of Magnetism and Ritual of Crushing.
This commit is contained in:
parent
6e3f1b3a4e
commit
4ac0f31124
|
@ -58,7 +58,7 @@ public class EntitySoulSnare extends ProjectileItemEntity
|
|||
|
||||
if (result.getEntity() instanceof LivingEntity)
|
||||
{
|
||||
((LivingEntity) result.getEntity()).addPotionEffect(new EffectInstance(BloodMagicPotions.soulSnare, 300, 0));
|
||||
((LivingEntity) result.getEntity()).addPotionEffect(new EffectInstance(BloodMagicPotions.SOUL_SNARE, 300, 0));
|
||||
|
||||
result.getEntity().attackEntityFrom(DamageSource.causeThrownDamage(this, this.func_234616_v_()), (float) 0);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,31 @@ package wayoftime.bloodmagic.util;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.FlowingFluidBlock;
|
||||
import net.minecraft.block.NetherPortalBlock;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.ISidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.potion.Effects;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.IFluidBlock;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import wayoftime.bloodmagic.tile.TileInventory;
|
||||
|
||||
|
@ -55,4 +78,371 @@ public class Utils
|
|||
{
|
||||
return String.valueOf(input.charAt(0)).toUpperCase(Locale.ENGLISH) + input.substring(1);
|
||||
}
|
||||
|
||||
public static boolean isImmuneToFireDamage(LivingEntity entity)
|
||||
{
|
||||
return entity.isImmuneToFire() || entity.isPotionActive(Effects.FIRE_RESISTANCE);
|
||||
}
|
||||
|
||||
public static boolean isBlockLiquid(BlockState state)
|
||||
{
|
||||
return (state instanceof IFluidBlock || state.getMaterial().isLiquid());
|
||||
}
|
||||
|
||||
public static boolean isFlowingLiquid(World world, BlockPos pos, BlockState state)
|
||||
{
|
||||
Block block = state.getBlock();
|
||||
return ((block instanceof IFluidBlock && Math.abs(((IFluidBlock) block).getFilledPercentage(world, pos)) == 1)
|
||||
|| (block instanceof FlowingFluidBlock
|
||||
&& !((FlowingFluidBlock) block).getFluidState(state).isSource()));
|
||||
}
|
||||
|
||||
public static boolean spawnStackAtBlock(World world, BlockPos pos, @Nullable Direction pushDirection, ItemStack stack)
|
||||
{
|
||||
BlockPos spawnPos = new BlockPos(pos);
|
||||
|
||||
double velX = 0;
|
||||
double velY = 0;
|
||||
double velZ = 0;
|
||||
double velocity = 0.15D;
|
||||
if (pushDirection != null)
|
||||
{
|
||||
spawnPos = spawnPos.offset(pushDirection);
|
||||
|
||||
switch (pushDirection)
|
||||
{
|
||||
case DOWN:
|
||||
{
|
||||
velY = -velocity;
|
||||
break;
|
||||
}
|
||||
case UP:
|
||||
{
|
||||
velY = velocity;
|
||||
break;
|
||||
}
|
||||
case NORTH:
|
||||
{
|
||||
velZ = -velocity;
|
||||
break;
|
||||
}
|
||||
case SOUTH:
|
||||
{
|
||||
velZ = velocity;
|
||||
break;
|
||||
}
|
||||
case WEST:
|
||||
{
|
||||
velX = -velocity;
|
||||
break;
|
||||
}
|
||||
case EAST:
|
||||
{
|
||||
velX = velocity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double posX = spawnPos.getX() + 0.5;
|
||||
double posY = spawnPos.getY() + 0.5;
|
||||
double posZ = spawnPos.getZ() + 0.5;
|
||||
|
||||
ItemEntity entityItem = new ItemEntity(world, posX, posY, posZ, stack);
|
||||
entityItem.setVelocity(velX, velY, velZ);
|
||||
|
||||
entityItem.setItem(stack);
|
||||
return world.addEntity(entityItem);
|
||||
}
|
||||
|
||||
public static boolean swapLocations(World initialWorld, BlockPos initialPos, World finalWorld, BlockPos finalPos)
|
||||
{
|
||||
return swapLocations(initialWorld, initialPos, finalWorld, finalPos, true);
|
||||
}
|
||||
|
||||
public static boolean swapLocations(World initialWorld, BlockPos initialPos, World finalWorld, BlockPos finalPos, boolean playSound)
|
||||
{
|
||||
TileEntity initialTile = initialWorld.getTileEntity(initialPos);
|
||||
TileEntity finalTile = finalWorld.getTileEntity(finalPos);
|
||||
CompoundNBT initialTag = new CompoundNBT();
|
||||
CompoundNBT finalTag = new CompoundNBT();
|
||||
if (initialTile != null)
|
||||
initialTile.write(initialTag);
|
||||
if (finalTile != null)
|
||||
finalTile.write(finalTag);
|
||||
|
||||
BlockState initialState = initialWorld.getBlockState(initialPos);
|
||||
BlockState finalState = finalWorld.getBlockState(finalPos);
|
||||
|
||||
if ((initialState.getBlock().equals(Blocks.AIR) && finalState.getBlock().equals(Blocks.AIR))
|
||||
|| initialState.getBlock() instanceof NetherPortalBlock
|
||||
|| finalState.getBlock() instanceof NetherPortalBlock)
|
||||
return false;
|
||||
|
||||
if (playSound)
|
||||
{
|
||||
initialWorld.playSound(initialPos.getX(), initialPos.getY(), initialPos.getZ(), SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false);
|
||||
finalWorld.playSound(finalPos.getX(), finalPos.getY(), finalPos.getZ(), SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.AMBIENT, 1.0F, 1.0F, false);
|
||||
}
|
||||
|
||||
// Finally, we get to do something! (CLEARING TILES)
|
||||
if (finalState.getBlock().hasTileEntity(finalState))
|
||||
finalWorld.removeTileEntity(finalPos);
|
||||
if (initialState.getBlock().hasTileEntity(initialState))
|
||||
initialWorld.removeTileEntity(initialPos);
|
||||
|
||||
// TILES CLEARED
|
||||
BlockState initialBlockState = initialWorld.getBlockState(initialPos);
|
||||
BlockState finalBlockState = finalWorld.getBlockState(finalPos);
|
||||
finalWorld.setBlockState(finalPos, initialBlockState, 3);
|
||||
|
||||
if (initialTile != null)
|
||||
{
|
||||
// TileEntity newTileInitial = TileEntity.create(finalWorld, initialTag);
|
||||
TileEntity newTileInitial = TileEntity.readTileEntity(finalBlockState, initialTag);
|
||||
|
||||
finalWorld.setTileEntity(finalPos, newTileInitial);
|
||||
// newTileInitial.setPos(finalPos);
|
||||
newTileInitial.setWorldAndPos(finalWorld, finalPos);
|
||||
}
|
||||
|
||||
initialWorld.setBlockState(initialPos, finalBlockState, 3);
|
||||
|
||||
if (finalTile != null)
|
||||
{
|
||||
// TileEntity newTileFinal = TileEntity.create(initialWorld, finalTag);
|
||||
TileEntity newTileFinal = TileEntity.readTileEntity(initialBlockState, finalTag);
|
||||
|
||||
initialWorld.setTileEntity(initialPos, newTileFinal);
|
||||
// newTileFinal.setPos(initialPos);
|
||||
newTileFinal.setWorldAndPos(initialWorld, initialPos);
|
||||
}
|
||||
|
||||
initialWorld.notifyNeighborsOfStateChange(initialPos, finalState.getBlock());
|
||||
finalWorld.notifyNeighborsOfStateChange(finalPos, initialState.getBlock());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ItemStack insertStackIntoTile(ItemStack stack, TileEntity tile, Direction dir)
|
||||
{
|
||||
LazyOptional<IItemHandler> capability = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir);
|
||||
if (capability.isPresent())
|
||||
{
|
||||
IItemHandler handler = capability.resolve().get();
|
||||
|
||||
return insertStackIntoTile(stack, handler);
|
||||
} else if (tile instanceof IInventory)
|
||||
{
|
||||
return insertStackIntoInventory(stack, (IInventory) tile, dir);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static ItemStack insertStackIntoTile(ItemStack stack, IItemHandler handler)
|
||||
{
|
||||
int numberOfSlots = handler.getSlots();
|
||||
|
||||
ItemStack copyStack = stack.copy();
|
||||
|
||||
for (int slot = 0; slot < numberOfSlots; slot++)
|
||||
{
|
||||
copyStack = handler.insertItem(slot, copyStack, false);
|
||||
if (copyStack.isEmpty())
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
return copyStack;
|
||||
}
|
||||
|
||||
public static int getNumberOfFreeSlots(TileEntity tile, Direction dir)
|
||||
{
|
||||
int slots = 0;
|
||||
|
||||
LazyOptional<IItemHandler> capability = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, dir);
|
||||
if (capability.isPresent())
|
||||
{
|
||||
IItemHandler handler = capability.resolve().get();
|
||||
|
||||
for (int i = 0; i < handler.getSlots(); i++)
|
||||
{
|
||||
if (handler.getStackInSlot(i).isEmpty())
|
||||
{
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
} else if (tile instanceof IInventory)
|
||||
{
|
||||
for (int i = 0; i < ((IInventory) tile).getSizeInventory(); i++)
|
||||
{
|
||||
if (((IInventory) tile).getStackInSlot(i).isEmpty())
|
||||
{
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
public static ItemStack insertStackIntoInventory(ItemStack stack, IInventory inventory, Direction dir)
|
||||
{
|
||||
if (stack.isEmpty())
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
boolean[] canBeInserted = new boolean[inventory.getSizeInventory()];
|
||||
|
||||
if (inventory instanceof ISidedInventory)
|
||||
{
|
||||
int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir);
|
||||
for (int in : array)
|
||||
{
|
||||
canBeInserted[in] = inventory.isItemValidForSlot(in, stack)
|
||||
&& ((ISidedInventory) inventory).canInsertItem(in, stack, dir);
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (int i = 0; i < canBeInserted.length; i++)
|
||||
{
|
||||
canBeInserted[i] = inventory.isItemValidForSlot(i, stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSizeInventory(); i++)
|
||||
{
|
||||
if (!canBeInserted[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack[] combinedStacks = combineStacks(stack, inventory.getStackInSlot(i));
|
||||
stack = combinedStacks[0];
|
||||
inventory.setInventorySlotContents(i, combinedStacks[1]);
|
||||
|
||||
if (stack.isEmpty())
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static boolean canInsertStackFullyIntoInventory(ItemStack stack, IInventory inventory, Direction dir, boolean fillToLimit, int limit)
|
||||
{
|
||||
if (stack.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int itemsLeft = stack.getCount();
|
||||
|
||||
boolean[] canBeInserted = new boolean[inventory.getSizeInventory()];
|
||||
|
||||
if (inventory instanceof ISidedInventory)
|
||||
{
|
||||
int[] array = ((ISidedInventory) inventory).getSlotsForFace(dir);
|
||||
for (int in : array)
|
||||
{
|
||||
canBeInserted[in] = inventory.isItemValidForSlot(in, stack)
|
||||
&& ((ISidedInventory) inventory).canInsertItem(in, stack, dir);
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (int i = 0; i < canBeInserted.length; i++)
|
||||
{
|
||||
canBeInserted[i] = inventory.isItemValidForSlot(i, stack);
|
||||
}
|
||||
}
|
||||
|
||||
int numberMatching = 0;
|
||||
|
||||
if (fillToLimit)
|
||||
{
|
||||
for (int i = 0; i < inventory.getSizeInventory(); i++)
|
||||
{
|
||||
if (!canBeInserted[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack invStack = inventory.getStackInSlot(i);
|
||||
|
||||
if (!invStack.isEmpty() && ItemHandlerHelper.canItemStacksStack(stack, invStack))
|
||||
{
|
||||
numberMatching += invStack.getCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fillToLimit && limit < stack.getCount() + numberMatching)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < inventory.getSizeInventory(); i++)
|
||||
{
|
||||
if (!canBeInserted[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack invStack = inventory.getStackInSlot(i);
|
||||
boolean canCombine = ItemHandlerHelper.canItemStacksStack(stack, invStack);
|
||||
if (canCombine)
|
||||
{
|
||||
if (invStack.isEmpty())
|
||||
{
|
||||
itemsLeft = 0;
|
||||
} else
|
||||
{
|
||||
itemsLeft -= (invStack.getMaxStackSize() - invStack.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsLeft <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stack1 Stack that is placed into a slot
|
||||
* @param stack2 Slot content that stack1 is placed into
|
||||
* @return Stacks after stacking
|
||||
*/
|
||||
public static ItemStack[] combineStacks(ItemStack stack1, ItemStack stack2)
|
||||
{
|
||||
ItemStack[] returned = new ItemStack[2];
|
||||
|
||||
if (ItemHandlerHelper.canItemStacksStack(stack1, stack2))
|
||||
{
|
||||
int transferedAmount = stack2.isEmpty() ? stack1.getCount()
|
||||
: Math.min(stack2.getMaxStackSize() - stack2.getCount(), stack1.getCount());
|
||||
if (transferedAmount > 0)
|
||||
{
|
||||
ItemStack copyStack = stack1.split(transferedAmount);
|
||||
if (stack2.isEmpty())
|
||||
{
|
||||
stack2 = copyStack;
|
||||
} else
|
||||
{
|
||||
stack2.grow(transferedAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
returned[0] = stack1;
|
||||
returned[1] = stack2;
|
||||
|
||||
return returned;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,10 +72,10 @@ public class WillHandler
|
|||
DamageSource source = event.getSource();
|
||||
Entity entity = source.getTrueSource();
|
||||
|
||||
if (attackedEntity.isPotionActive(BloodMagicPotions.soulSnare) && (attackedEntity instanceof MobEntity
|
||||
if (attackedEntity.isPotionActive(BloodMagicPotions.SOUL_SNARE) && (attackedEntity instanceof MobEntity
|
||||
|| attackedEntity.getEntityWorld().getDifficulty() == Difficulty.PEACEFUL))
|
||||
{
|
||||
EffectInstance eff = attackedEntity.getActivePotionEffect(BloodMagicPotions.soulSnare);
|
||||
EffectInstance eff = attackedEntity.getActivePotionEffect(BloodMagicPotions.SOUL_SNARE);
|
||||
int lvl = eff.getAmplifier();
|
||||
|
||||
double amountOfSouls = attackedEntity.getEntityWorld().rand.nextDouble() * (lvl + 1) * (lvl + 1) * 4 + 1;
|
||||
|
|
|
@ -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…
Reference in a new issue