Ritual reimplementation

Reimplemented the following rituals:
	- Resonance of the Faceted Crystal
	- Crack of the Fractured Crystal
	- Reap of the Harvest Moon
This commit is contained in:
WayofTime 2020-11-26 13:32:56 -05:00
parent 907a0f27e7
commit e312e3d854
13 changed files with 955 additions and 4 deletions

View file

@ -0,0 +1,152 @@
package wayoftime.bloodmagic.ritual.harvest;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CropsBlock;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootParameters;
import net.minecraft.util.ResourceLocation;
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.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
import wayoftime.bloodmagic.util.BMLog;
/**
* Harvest handler for standard plantable crops such as Wheat, Potatoes, and
* Netherwart. <br>
* Register a new crop for this handler with
* {@link HarvestRegistry#registerStandardCrop(Block, int)}
*/
public class HarvestHandlerPlantable implements IHarvestHandler
{
private static final ItemStack mockHoe = new ItemStack(Items.DIAMOND_HOE, 1);
public HarvestHandlerPlantable()
{
HarvestRegistry.registerStandardCrop(Blocks.CARROTS, 7);
HarvestRegistry.registerStandardCrop(Blocks.WHEAT, 7);
HarvestRegistry.registerStandardCrop(Blocks.POTATOES, 7);
HarvestRegistry.registerStandardCrop(Blocks.BEETROOTS, 3);
HarvestRegistry.registerStandardCrop(Blocks.NETHER_WART, 3);
addThirdPartyCrop("actuallyadditions", "blockFlax", 7);
addThirdPartyCrop("actuallyadditions", "blockCanola", 7);
addThirdPartyCrop("actuallyadditions", "blockRice", 7);
addThirdPartyCrop("extrautils2", "redorchid", 6);
addThirdPartyCrop("extrautils2", "enderlily", 7);
addThirdPartyCrop("roots", "moonglow", 7);
addThirdPartyCrop("roots", "terra_moss", 7);
addThirdPartyCrop("roots", "pereskia", 7);
addThirdPartyCrop("roots", "wildroot", 7);
addThirdPartyCrop("roots", "aubergine", 7);
addThirdPartyCrop("roots", "spirit_herb", 7);
addPamCrops();
}
@Override
public boolean harvest(World world, BlockPos pos, BlockState state, List<ItemStack> drops)
{
// NonNullList<ItemStack> blockDrops = NonNullList.create();
// state.getBlock().getDrops(blockDrops, world, pos, state, 0);
boolean foundSeed = false;
LootContext.Builder lootBuilder = new LootContext.Builder((ServerWorld) world);
Vector3d blockCenter = new Vector3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
List<ItemStack> blockDrops = state.getDrops(lootBuilder.withParameter(LootParameters.field_237457_g_, blockCenter).withParameter(LootParameters.TOOL, mockHoe));
// System.out.println("Size of list: " + blockDrops.size());
for (ItemStack stack : blockDrops)
{
if (stack.isEmpty())
continue;
// This hurts my soul.
if (stack.getItem() instanceof BlockItem && ((BlockItem) stack.getItem()).getBlock() == state.getBlock())
{
stack.shrink(1);
foundSeed = true;
break;
}
}
// System.out.println("Found seed: " + foundSeed);
if (foundSeed)
{
world.setBlockState(pos, state.getBlock().getDefaultState());
world.playEvent(2001, pos, Block.getStateId(state));
for (ItemStack stack : blockDrops)
{
if (stack.isEmpty())
continue;
drops.add(stack);
}
return true;
}
return false;
}
@Override
public boolean test(World world, BlockPos pos, BlockState state)
{
// state.hasProperty(null);
return HarvestRegistry.getStandardCrops().containsKey(state.getBlock()) && state.getBlock() instanceof CropsBlock && ((CropsBlock) state.getBlock()).isMaxAge(state);
// return HarvestRegistry.getStandardCrops().containsKey(state.getBlock()) && state.getBlock().getMetaFromState(state) == HarvestRegistry.getStandardCrops().get(state.getBlock());
}
private static void addThirdPartyCrop(String modid, String regName, int matureMeta)
{
if (!ModList.get().isLoaded(modid))
return;
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(modid, regName));
if (block != null && block != Blocks.AIR)
HarvestRegistry.registerStandardCrop(block, matureMeta);
}
private static void addPamCrops()
{
if (!ModList.get().isLoaded("harvestcraft"))
return;
try
{
Class<?> pamRegistry = Class.forName("com.pam.harvestcraft.blocks.CropRegistry");
Field names = pamRegistry.getDeclaredField("cropNames");
Method getCrop = pamRegistry.getMethod("getCrop", String.class);
for (String name : (String[]) names.get(null))
{
CropsBlock crop = (CropsBlock) getCrop.invoke(null, name);
HarvestRegistry.registerStandardCrop(crop, crop.getMaxAge());
}
} catch (ClassNotFoundException e)
{
BMLog.DEFAULT.error("HarvestCraft integration cancelled; unable to find registry class");
} catch (NoSuchMethodException | NoSuchFieldException e)
{
BMLog.DEFAULT.error("HarvestCraft integration cancelled; unable to find crop name mapper");
} catch (IllegalAccessException | InvocationTargetException e)
{
BMLog.DEFAULT.error("HarvestCraft integration cancelled; crop name lookup broke");
}
}
}

View file

@ -0,0 +1,72 @@
package wayoftime.bloodmagic.ritual.harvest;
import java.util.Collection;
import java.util.List;
import net.minecraft.block.AttachedStemBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootParameters;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
/**
* Harvest handler for crops with stems such as Pumpkins and Melons. Rotation
* based crop blocks are a good reason to use this (see pumpkins). <br>
* Register a new crop for this handler with
* {@link HarvestRegistry#registerStemCrop(BlockState, BlockState)}
*/
public class HarvestHandlerStem implements IHarvestHandler
{
private static final ItemStack mockHoe = new ItemStack(Items.DIAMOND_HOE, 1);
public HarvestHandlerStem()
{
for (int i = 0; i < 4; i++)
{
Direction facing = Direction.byHorizontalIndex(i);
HarvestRegistry.registerStemCrop(Blocks.PUMPKIN.getDefaultState(), Blocks.ATTACHED_PUMPKIN_STEM.getDefaultState().with(AttachedStemBlock.FACING, facing));
HarvestRegistry.registerStemCrop(Blocks.MELON.getDefaultState(), Blocks.ATTACHED_MELON_STEM.getDefaultState().with(AttachedStemBlock.FACING, facing));
}
}
@Override
public boolean harvest(World world, BlockPos pos, BlockState state, List<ItemStack> drops)
{
Direction cropDir = state.get(AttachedStemBlock.FACING);
if (cropDir != Direction.UP)
{
BlockPos cropPos = pos.offset(cropDir);
BlockState probableCrop = world.getBlockState(cropPos);
Collection<BlockState> registeredCrops = HarvestRegistry.getStemCrops().get(state);
for (BlockState registeredCrop : registeredCrops)
{
if (registeredCrop == probableCrop)
{
LootContext.Builder lootBuilder = new LootContext.Builder((ServerWorld) world);
Vector3d blockCenter = new Vector3d(cropPos.getX() + 0.5, cropPos.getY() + 0.5, cropPos.getZ() + 0.5);
List<ItemStack> blockDrops = registeredCrop.getDrops(lootBuilder.withParameter(LootParameters.field_237457_g_, blockCenter).withParameter(LootParameters.TOOL, mockHoe));
drops.addAll(blockDrops);
world.destroyBlock(cropPos, false);
return true;
}
}
}
return false;
}
@Override
public boolean test(World world, BlockPos pos, BlockState state)
{
return HarvestRegistry.getStemCrops().containsKey(state);
}
}

View file

@ -0,0 +1,59 @@
package wayoftime.bloodmagic.ritual.harvest;
import java.util.List;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CactusBlock;
import net.minecraft.block.SugarCaneBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.LootContext;
import net.minecraft.loot.LootParameters;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
/**
* Harvest handler for crops that grow vertically such as Sugar Cane and Cactus.
* <br>
* Register a new crop for this handler with
* {@link HarvestRegistry#registerTallCrop(BlockState)}
*/
public class HarvestHandlerTall implements IHarvestHandler
{
private static final ItemStack mockHoe = new ItemStack(Items.DIAMOND_HOE, 1);
public HarvestHandlerTall()
{
for (int i = 0; i < 15; i++)
{
HarvestRegistry.registerTallCrop(Blocks.SUGAR_CANE.getDefaultState().with(SugarCaneBlock.AGE, i));
HarvestRegistry.registerTallCrop(Blocks.CACTUS.getDefaultState().with(CactusBlock.AGE, i));
}
}
@Override
public boolean harvest(World world, BlockPos pos, BlockState state, List<ItemStack> drops)
{
BlockState up = world.getBlockState(pos.up());
if (up.getBlock() == state.getBlock())
{
LootContext.Builder lootBuilder = new LootContext.Builder((ServerWorld) world);
Vector3d blockCenter = new Vector3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
List<ItemStack> blockDrops = state.getDrops(lootBuilder.withParameter(LootParameters.field_237457_g_, blockCenter).withParameter(LootParameters.TOOL, mockHoe));
drops.addAll(blockDrops);
world.destroyBlock(pos.up(), false);
return true;
}
return false;
}
@Override
public boolean test(World world, BlockPos pos, BlockState state)
{
return HarvestRegistry.getTallCrops().contains(state);
}
}

View file

@ -0,0 +1,125 @@
package wayoftime.bloodmagic.ritual.harvest;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import net.minecraft.block.AttachedStemBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.StemBlock;
public class HarvestRegistry
{
private static final List<IHarvestHandler> HARVEST_HANDLERS = Lists.newArrayList();
private static final Map<Block, Integer> STANDARD_CROPS = Maps.newHashMap();
private static final Set<BlockState> TALL_CROPS = Sets.newHashSet();
private static final Multimap<BlockState, BlockState> STEM_CROPS = ArrayListMultimap.create();
private static final Map<BlockState, Integer> AMPLIFIERS = Maps.newHashMap();
/**
* Registers a handler for the Harvest Ritual to call.
*
* @param handler - The custom handler to register
*/
public static void registerHandler(IHarvestHandler handler)
{
if (!HARVEST_HANDLERS.contains(handler))
HARVEST_HANDLERS.add(handler);
}
/**
* Registers a standard crop (IE: Wheat, Carrots, Potatoes, Netherwart, etc) for
* the {@link WayofTime.bloodmagic.ritual.harvest.HarvestHandlerPlantable}
* handler to handle.
*
* @param crop - The crop block to handle.
* @param matureMeta - The meta value at which the crop is considered mature and
* ready to be harvested.
*/
public static void registerStandardCrop(Block crop, int matureMeta)
{
if (!STANDARD_CROPS.containsKey(crop))
STANDARD_CROPS.put(crop, matureMeta);
}
/**
* Registers a tall crop (Sugar Cane and Cactus) for the
* {@link WayofTime.bloodmagic.ritual.harvest.HarvestHandlerTall} handler to
* handle.
*
* @param crop - The crop block to handle.
*/
public static void registerTallCrop(BlockState crop)
{
if (!TALL_CROPS.contains(crop))
TALL_CROPS.add(crop);
}
/**
* Registers a stem crop (Melon and Pumpkin) for the
* {@link WayofTime.bloodmagic.ritual.harvest.HarvestHandlerStem} handler to
* handle.
* <p>
* Use {@link net.minecraftforge.oredict.OreDictionary#WILDCARD_VALUE} to accept
* any meta for the crop block.
* <p>
* The Stem must be instanceof {@link StemBlock}
*
* @param crop - The crop block to handle.
* @param stem - The stem of the crop
*/
public static void registerStemCrop(BlockState crop, BlockState stem)
{
if (!STEM_CROPS.containsKey(crop) && stem.getBlock() instanceof AttachedStemBlock)
STEM_CROPS.put(stem, crop);
}
/**
* Registers a range amplifier for the Harvest Ritual.
*
* @param block - The block for the amplifier.
* @param range - The range the amplifier provides.
*/
public static void registerRangeAmplifier(BlockState block, int range)
{
if (!AMPLIFIERS.containsKey(block))
AMPLIFIERS.put(block, range);
}
public static List<IHarvestHandler> getHarvestHandlers()
{
return ImmutableList.copyOf(HARVEST_HANDLERS);
}
public static Map<Block, Integer> getStandardCrops()
{
return ImmutableMap.copyOf(STANDARD_CROPS);
}
public static Set<BlockState> getTallCrops()
{
return ImmutableSet.copyOf(TALL_CROPS);
}
public static Multimap<BlockState, BlockState> getStemCrops()
{
return ImmutableMultimap.copyOf(STEM_CROPS);
}
public static Map<BlockState, Integer> getAmplifiers()
{
return ImmutableMap.copyOf(AMPLIFIERS);
}
}

View file

@ -0,0 +1,39 @@
package wayoftime.bloodmagic.ritual.harvest;
import java.util.List;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* Used to define a HarvestHandler for the Harvest Ritual.
*/
public interface IHarvestHandler
{
/**
* Called whenever the Harvest Ritual attempts to harvest a block. <br>
* Use this to break the block and plant a new one. <br>
* Add the items to be dropped to the drops list. <br>
*
* @param world - The world
* @param pos - The position of the {@link BlockState} being checked
* @param state - The {@link BlockState} being checked
* @param drops - The items to be dropped
* @return If the block was successfully harvested.
*/
boolean harvest(World world, BlockPos pos, BlockState state, List<ItemStack> drops);
/**
* Tests to see if the block is valid for harvest.
*
* @param world The world
* @param pos The position in the world of the {@link BlockState} being
* checked
* @param state The {@link BlockState} being checked
* @return if this block is valid for harvest.
*/
boolean test(World world, BlockPos pos, BlockState state);
}