Implemented the Mob Sacrifice Array.
Needs some cleaning up + added visuals, but appears functional.
This commit is contained in:
parent
32227afd9d
commit
389043dc64
|
@ -11,7 +11,8 @@ import javax.annotation.Nullable;
|
|||
/**
|
||||
* Allows recipe addition and removal.
|
||||
*/
|
||||
public interface IBloodMagicRecipeRegistrar {
|
||||
public interface IBloodMagicRecipeRegistrar
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds a new recipe to the Blood Altar.
|
||||
|
@ -54,7 +55,7 @@ public interface IBloodMagicRecipeRegistrar {
|
|||
|
||||
/**
|
||||
* Adds a new recipe to the Soul/Tartaric Forge.
|
||||
*
|
||||
*
|
||||
* @param output An output {@link ItemStack}.
|
||||
* @param minimumSouls The minimum number of souls that must be contained in the Soul Gem.
|
||||
* @param soulDrain The number of souls to drain from the Soul Gem.
|
||||
|
@ -65,8 +66,8 @@ public interface IBloodMagicRecipeRegistrar {
|
|||
/**
|
||||
* Removes a Soul/Tartaric Forge recipe based on an input {@link ItemStack} array.
|
||||
*
|
||||
* @param input The input items to remove the recipe of.
|
||||
* @return Whether or not a recipe was removed.
|
||||
* @param input The input items to remove the recipe of.
|
||||
* @return Whether or not a recipe was removed.
|
||||
*/
|
||||
boolean removeTartaricForge(@Nonnull ItemStack... input);
|
||||
|
||||
|
@ -88,4 +89,8 @@ public interface IBloodMagicRecipeRegistrar {
|
|||
* @return Whether or not a recipe was removed.
|
||||
*/
|
||||
boolean removeAlchemyArray(@Nonnull ItemStack input, @Nonnull ItemStack catalyst);
|
||||
|
||||
void addSacrificeCraft(@Nonnull ItemStack output, @Nonnegative double healthRequired, @Nonnull Ingredient... input);
|
||||
|
||||
boolean removeSacrificeCraft(@Nonnull ItemStack... input);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
package WayofTime.bloodmagic.alchemyArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.EntityEntry;
|
||||
import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||
import WayofTime.bloodmagic.api.impl.BloodMagicAPI;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeSacrificeCraft;
|
||||
import WayofTime.bloodmagic.ritual.AreaDescriptor;
|
||||
import WayofTime.bloodmagic.util.DamageSourceBloodMagic;
|
||||
import WayofTime.bloodmagic.util.helper.PurificationHelper;
|
||||
|
||||
public class AlchemyArrayEffectMobSacrifice extends AlchemyArrayEffect
|
||||
{
|
||||
public static final AreaDescriptor itemDescriptor = new AreaDescriptor.Rectangle(new BlockPos(-5, -5, -5), 11);
|
||||
public static final AreaDescriptor mobDescriptor = new AreaDescriptor.Rectangle(new BlockPos(-5, -5, -5), 11);
|
||||
|
||||
public AlchemyArrayEffectMobSacrifice(String key)
|
||||
{
|
||||
super(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(TileEntity tile, int ticksActive)
|
||||
{
|
||||
World world = tile.getWorld();
|
||||
if (world.isRemote && ticksActive < 200 && ticksActive > 40)
|
||||
{
|
||||
BlockPos pos = tile.getPos();
|
||||
Random rand = world.rand;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
double d0 = (double) pos.getX() + 0.5D + (rand.nextDouble() - 0.5D) * 2.5D;
|
||||
double d1 = (double) pos.getY() + 0.2D + (rand.nextDouble() - 0.5D) * 0.2D;
|
||||
double d2 = (double) pos.getZ() + 0.5D + (rand.nextDouble() - 0.5D) * 2.5D;
|
||||
world.spawnParticle(EnumParticleTypes.SPELL_MOB, d0, d1, d2, 1D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isRemote)
|
||||
{
|
||||
if (ticksActive >= 200)
|
||||
{
|
||||
BlockPos pos = tile.getPos();
|
||||
|
||||
List<EntityItem> itemList = world.getEntitiesWithinAABB(EntityItem.class, itemDescriptor.getAABB(pos));
|
||||
|
||||
List<ItemStack> inputList = new ArrayList<ItemStack>();
|
||||
|
||||
for (EntityItem entityItem : itemList)
|
||||
{
|
||||
if (entityItem.isDead || entityItem.getItem().isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
inputList.add(entityItem.getItem().copy());
|
||||
}
|
||||
|
||||
if (inputList.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inputList.size() == 1) //TODO: Test if it is a something that can be filled with Soul Breath
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RecipeSacrificeCraft recipe = BloodMagicAPI.INSTANCE.getRecipeRegistrar().getSacrificeCraft(inputList);
|
||||
if (recipe != null)
|
||||
{
|
||||
double healthRequired = recipe.getHealthRequired();
|
||||
double healthAvailable = 0;
|
||||
|
||||
List<EntityLivingBase> livingEntities = world.getEntitiesWithinAABB(EntityLivingBase.class, mobDescriptor.getAABB(pos));
|
||||
for (EntityLivingBase living : livingEntities)
|
||||
{
|
||||
double health = getEffectiveHealth(living);
|
||||
if (health > 0)
|
||||
{
|
||||
healthAvailable += health;
|
||||
}
|
||||
}
|
||||
|
||||
if (healthAvailable < healthRequired)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (EntityLivingBase living : livingEntities)
|
||||
{
|
||||
double health = getEffectiveHealth(living);
|
||||
if (health > 0)
|
||||
{
|
||||
healthAvailable -= health;
|
||||
living.getEntityWorld().playSound(null, living.posX, living.posY, living.posZ, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 0.5F, 2.6F + (living.getEntityWorld().rand.nextFloat() - living.getEntityWorld().rand.nextFloat()) * 0.8F);
|
||||
living.setHealth(-1);
|
||||
living.onDeath(DamageSourceBloodMagic.INSTANCE);
|
||||
}
|
||||
|
||||
if (healthAvailable <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (EntityItem itemEntity : itemList)
|
||||
{
|
||||
itemEntity.getItem().setCount(itemEntity.getItem().getCount() - 1);
|
||||
if (itemEntity.getItem().isEmpty()) //TODO: Check container
|
||||
{
|
||||
itemEntity.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
world.spawnEntity(new EntityItem(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, recipe.getOutput()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//Future-proofing in case I want to make different mobs give different effective health
|
||||
public double getEffectiveHealth(EntityLivingBase living)
|
||||
{
|
||||
if (living == null)
|
||||
return 0;
|
||||
|
||||
if (!living.isNonBoss())
|
||||
return 0;
|
||||
|
||||
if (living instanceof EntityPlayer)
|
||||
return 0;
|
||||
|
||||
if (living.isChild() && !(living instanceof IMob))
|
||||
return 0;
|
||||
|
||||
if (living.isDead || living.getHealth() < 0.5F)
|
||||
return 0;
|
||||
|
||||
EntityEntry entityEntry = EntityRegistry.getEntry(living.getClass());
|
||||
if (entityEntry == null)
|
||||
return 0;
|
||||
|
||||
return living.getHealth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound tag)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlchemyArrayEffect getNewCopy()
|
||||
{
|
||||
return new AlchemyArrayEffectMobSacrifice(key);
|
||||
}
|
||||
}
|
|
@ -25,10 +25,12 @@ import net.minecraftforge.fml.common.registry.EntityEntry;
|
|||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
|
||||
@BloodMagicPlugin
|
||||
public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
||||
public class BloodMagicCorePlugin implements IBloodMagicPlugin
|
||||
{
|
||||
|
||||
@Override
|
||||
public void register(IBloodMagicAPI apiInterface) {
|
||||
public void register(IBloodMagicAPI apiInterface)
|
||||
{
|
||||
BloodMagicAPI api = (BloodMagicAPI) apiInterface;
|
||||
// Add forced blacklistings
|
||||
api.getBlacklist().addTeleposer(RegistrarBloodMagicBlocks.INPUT_ROUTING_NODE);
|
||||
|
@ -82,15 +84,19 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(IBloodMagicRecipeRegistrar recipeRegistrar) {
|
||||
public void registerRecipes(IBloodMagicRecipeRegistrar recipeRegistrar)
|
||||
{
|
||||
RegistrarBloodMagicRecipes.registerAltarRecipes((BloodMagicRecipeRegistrar) recipeRegistrar);
|
||||
RegistrarBloodMagicRecipes.registerAlchemyTableRecipes((BloodMagicRecipeRegistrar) recipeRegistrar);
|
||||
RegistrarBloodMagicRecipes.registerTartaricForgeRecipes((BloodMagicRecipeRegistrar) recipeRegistrar);
|
||||
RegistrarBloodMagicRecipes.registerAlchemyArrayRecipes((BloodMagicRecipeRegistrar) recipeRegistrar);
|
||||
RegistrarBloodMagicRecipes.registerSacrificeCraftRecipes((BloodMagicRecipeRegistrar) recipeRegistrar);
|
||||
}
|
||||
|
||||
private static void handleConfigValues(BloodMagicAPI api) {
|
||||
for (String value : ConfigHandler.values.sacrificialValues) {
|
||||
private static void handleConfigValues(BloodMagicAPI api)
|
||||
{
|
||||
for (String value : ConfigHandler.values.sacrificialValues)
|
||||
{
|
||||
String[] split = value.split(";");
|
||||
if (split.length != 2) // Not valid format
|
||||
continue;
|
||||
|
@ -98,15 +104,18 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
api.getValueManager().setSacrificialValue(new ResourceLocation(split[0]), Integer.parseInt(split[1]));
|
||||
}
|
||||
|
||||
for (String value : ConfigHandler.blacklist.teleposer) {
|
||||
for (String value : ConfigHandler.blacklist.teleposer)
|
||||
{
|
||||
EntityEntry entityEntry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(value));
|
||||
if (entityEntry == null) { // It's not an entity (or at least not a valid one), so let's try a block.
|
||||
if (entityEntry == null)
|
||||
{ // It's not an entity (or at least not a valid one), so let's try a block.
|
||||
String[] blockData = value.split("\\[");
|
||||
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(blockData[0]));
|
||||
if (block == Blocks.AIR || block == null) // Not a valid block either
|
||||
continue;
|
||||
|
||||
if (blockData.length > 1) { // We have properties listed, so let's build a state.
|
||||
if (blockData.length > 1)
|
||||
{ // We have properties listed, so let's build a state.
|
||||
api.getBlacklist().addTeleposer(parseState(value));
|
||||
continue;
|
||||
}
|
||||
|
@ -118,13 +127,15 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
api.getBlacklist().addTeleposer(entityEntry.getRegistryName());
|
||||
}
|
||||
|
||||
for (String value : ConfigHandler.blacklist.transposer) {
|
||||
for (String value : ConfigHandler.blacklist.transposer)
|
||||
{
|
||||
String[] blockData = value.split("\\[");
|
||||
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(blockData[0]));
|
||||
if (block == Blocks.AIR || block == null) // Not a valid block
|
||||
continue;
|
||||
|
||||
if (blockData.length > 1) { // We have properties listed, so let's build a state.
|
||||
if (blockData.length > 1)
|
||||
{ // We have properties listed, so let's build a state.
|
||||
api.getBlacklist().addTeleposer(parseState(value));
|
||||
continue;
|
||||
}
|
||||
|
@ -132,7 +143,8 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
api.getBlacklist().addTeleposer(block);
|
||||
}
|
||||
|
||||
for (String value : ConfigHandler.blacklist.wellOfSuffering) {
|
||||
for (String value : ConfigHandler.blacklist.wellOfSuffering)
|
||||
{
|
||||
EntityEntry entityEntry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(value));
|
||||
if (entityEntry == null) // Not a valid entity
|
||||
continue;
|
||||
|
@ -141,7 +153,8 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
private static IBlockState parseState(String blockInfo) {
|
||||
private static IBlockState parseState(String blockInfo)
|
||||
{
|
||||
String[] split = blockInfo.split("\\[");
|
||||
split[1] = split[1].substring(0, split[1].lastIndexOf("]")); // Make sure brackets are removed from state
|
||||
|
||||
|
@ -154,7 +167,8 @@ public class BloodMagicCorePlugin implements IBloodMagicPlugin {
|
|||
|
||||
// Force our values into the state
|
||||
String[] stateValues = split[1].split(","); // Splits up each value
|
||||
for (String value : stateValues) {
|
||||
for (String value : stateValues)
|
||||
{
|
||||
String[] valueSplit = value.split("="); // Separates property and value
|
||||
IProperty property = blockState.getProperty(valueSplit[0]);
|
||||
if (property != null)
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
package WayofTime.bloodmagic.api.impl;
|
||||
|
||||
import WayofTime.bloodmagic.api.IBloodMagicRecipeRegistrar;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyArray;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyTable;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeBloodAltar;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeTartaricForge;
|
||||
import WayofTime.bloodmagic.orb.IBloodOrb;
|
||||
import WayofTime.bloodmagic.core.recipe.IngredientBloodOrb;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import javax.annotation.Nonnegative;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import WayofTime.bloodmagic.api.IBloodMagicRecipeRegistrar;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyArray;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyTable;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeBloodAltar;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeSacrificeCraft;
|
||||
import WayofTime.bloodmagic.api.impl.recipe.RecipeTartaricForge;
|
||||
import WayofTime.bloodmagic.core.recipe.IngredientBloodOrb;
|
||||
import WayofTime.bloodmagic.orb.IBloodOrb;
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public class BloodMagicRecipeRegistrar implements IBloodMagicRecipeRegistrar
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ public class BloodMagicRecipeRegistrar implements IBloodMagicRecipeRegistrar
|
|||
private final Set<RecipeAlchemyTable> alchemyRecipes;
|
||||
private final Set<RecipeTartaricForge> tartaricForgeRecipes;
|
||||
private final Set<RecipeAlchemyArray> alchemyArrayRecipes;
|
||||
private final Set<RecipeSacrificeCraft> sacrificeCraftRecipes;
|
||||
|
||||
public BloodMagicRecipeRegistrar()
|
||||
{
|
||||
|
@ -41,6 +42,7 @@ public class BloodMagicRecipeRegistrar implements IBloodMagicRecipeRegistrar
|
|||
this.alchemyRecipes = Sets.newHashSet();
|
||||
this.tartaricForgeRecipes = Sets.newHashSet();
|
||||
this.alchemyArrayRecipes = Sets.newHashSet();
|
||||
this.sacrificeCraftRecipes = Sets.newHashSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,6 +191,49 @@ public class BloodMagicRecipeRegistrar implements IBloodMagicRecipeRegistrar
|
|||
addAlchemyArray(Ingredient.fromStacks(input), Ingredient.fromStacks(catalyst), output, circleTexture);
|
||||
}
|
||||
|
||||
public void addSacrificeCraft(@Nonnull ItemStack output, @Nonnegative double healthRequired, @Nonnull Object... input)
|
||||
{
|
||||
Preconditions.checkNotNull(output, "output cannot be null.");
|
||||
Preconditions.checkArgument(healthRequired >= 0, "healthRequired cannot be negative.");
|
||||
Preconditions.checkNotNull(input, "input cannot be null.");
|
||||
|
||||
List<Ingredient> ingredients = Lists.newArrayList();
|
||||
for (Object object : input)
|
||||
{
|
||||
if (object instanceof ItemStack && ((ItemStack) object).getItem() instanceof IBloodOrb)
|
||||
{
|
||||
ingredients.add(new IngredientBloodOrb(((IBloodOrb) ((ItemStack) object).getItem()).getOrb((ItemStack) object)));
|
||||
continue;
|
||||
}
|
||||
|
||||
ingredients.add(CraftingHelper.getIngredient(object));
|
||||
}
|
||||
|
||||
addSacrificeCraft(output, healthRequired, ingredients.toArray(new Ingredient[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeSacrificeCraft(@Nonnull ItemStack... input)
|
||||
{
|
||||
Preconditions.checkNotNull(input, "inputs cannot be null.");
|
||||
|
||||
for (ItemStack stack : input)
|
||||
Preconditions.checkNotNull(stack, "input cannot be null.");
|
||||
|
||||
return sacrificeCraftRecipes.remove(getSacrificeCraft(Lists.newArrayList(input)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSacrificeCraft(@Nonnull ItemStack output, @Nonnegative double healthRequired, @Nonnull Ingredient... input)
|
||||
{
|
||||
Preconditions.checkNotNull(output, "output cannot be null.");
|
||||
Preconditions.checkArgument(healthRequired >= 0, "healthRequired cannot be negative.");
|
||||
Preconditions.checkNotNull(input, "input cannot be null.");
|
||||
|
||||
NonNullList<Ingredient> inputs = NonNullList.from(Ingredient.EMPTY, input);
|
||||
sacrificeCraftRecipes.add(new RecipeSacrificeCraft(inputs, output, healthRequired));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RecipeBloodAltar getBloodAltar(@Nonnull ItemStack input)
|
||||
{
|
||||
|
@ -279,6 +324,44 @@ public class BloodMagicRecipeRegistrar implements IBloodMagicRecipeRegistrar
|
|||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RecipeSacrificeCraft getSacrificeCraft(@Nonnull List<ItemStack> input)
|
||||
{
|
||||
Preconditions.checkNotNull(input, "input cannot be null.");
|
||||
if (input.isEmpty())
|
||||
return null;
|
||||
|
||||
mainLoop: for (RecipeSacrificeCraft recipe : sacrificeCraftRecipes)
|
||||
{
|
||||
if (recipe.getInput().size() != input.size())
|
||||
continue;
|
||||
|
||||
List<Ingredient> recipeInput = new ArrayList<>(recipe.getInput());
|
||||
|
||||
for (int i = 0; i < input.size(); i++)
|
||||
{
|
||||
boolean matched = false;
|
||||
for (int j = 0; j < recipeInput.size(); j++)
|
||||
{
|
||||
Ingredient ingredient = recipeInput.get(j);
|
||||
if (ingredient.apply(input.get(i)))
|
||||
{
|
||||
matched = true;
|
||||
recipeInput.remove(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
continue mainLoop;
|
||||
}
|
||||
|
||||
return recipe;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RecipeAlchemyArray getAlchemyArray(@Nonnull ItemStack input, @Nonnull ItemStack catalyst)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package WayofTime.bloodmagic.api.impl.recipe;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class RecipeSacrificeCraft
|
||||
{
|
||||
@Nonnull
|
||||
private final NonNullList<Ingredient> input;
|
||||
@Nonnull
|
||||
private final ItemStack output;
|
||||
@Nonnegative
|
||||
private final double healthRequired;
|
||||
|
||||
public RecipeSacrificeCraft(@Nonnull NonNullList<Ingredient> input, @Nonnull ItemStack output, @Nonnegative double healthRequired)
|
||||
{
|
||||
Preconditions.checkNotNull(input, "input cannot be null.");
|
||||
Preconditions.checkNotNull(output, "output cannot be null.");
|
||||
Preconditions.checkArgument(healthRequired >= 0, "healthRequired cannot be negative.");
|
||||
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.healthRequired = healthRequired;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public final NonNullList<Ingredient> getInput()
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public final ItemStack getOutput()
|
||||
{
|
||||
return output;
|
||||
}
|
||||
|
||||
@Nonnegative
|
||||
public final double getHealthRequired()
|
||||
{
|
||||
return healthRequired;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
package WayofTime.bloodmagic.client.render.alchemyArray;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.tile.TileAlchemyArray;
|
||||
|
||||
public class MobSacrificeAlchemyCircleRenderer extends AlchemyCircleRenderer
|
||||
{
|
||||
private ResourceLocation bottomArrayResource = new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/MovementArray.png");
|
||||
|
||||
private ResourceLocation mobSacrificeSwirlResource = new ResourceLocation("bloodmagic", "textures/models/mobsacrificeswirl.png");
|
||||
|
||||
public MobSacrificeAlchemyCircleRenderer(ResourceLocation location)
|
||||
{
|
||||
super(location);
|
||||
}
|
||||
|
||||
public MobSacrificeAlchemyCircleRenderer()
|
||||
{
|
||||
this(new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/mobsacrifice.png"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSizeModifier(float craftTime)
|
||||
{
|
||||
if (craftTime < 40)
|
||||
{
|
||||
return 0;
|
||||
} else if (craftTime > 40 && craftTime < 100)
|
||||
{
|
||||
return (craftTime - 40) / 60f;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRotation(float craftTime)
|
||||
{
|
||||
float offset = 50;
|
||||
if (craftTime >= offset)
|
||||
{
|
||||
float modifier = (craftTime - offset) * 5f;
|
||||
return modifier * 1f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSecondaryRotation(float craftTime)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAt(TileEntity tile, double x, double y, double z, float craftTime)
|
||||
{
|
||||
if (!(tile instanceof TileAlchemyArray))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TileAlchemyArray tileArray = (TileAlchemyArray) tile;
|
||||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder wr = tessellator.getBuffer();
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
float rot = getRotation(craftTime);
|
||||
|
||||
float size = 1.0F * getSizeModifier(craftTime);
|
||||
|
||||
// Bind the texture to the circle
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(arrayResource);
|
||||
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(770, 1);
|
||||
|
||||
GlStateManager.translate(x, y, z);
|
||||
|
||||
// Specify which face this "circle" is located on
|
||||
EnumFacing sideHit = EnumFacing.UP;
|
||||
EnumFacing rotation = tileArray.getRotation();
|
||||
|
||||
GlStateManager.translate(sideHit.getFrontOffsetX() * offsetFromFace, sideHit.getFrontOffsetY() * offsetFromFace, sideHit.getFrontOffsetZ() * offsetFromFace);
|
||||
|
||||
switch (sideHit)
|
||||
{
|
||||
case DOWN:
|
||||
GlStateManager.translate(0, 0, 1);
|
||||
GlStateManager.rotate(-90.0f, 1, 0, 0);
|
||||
break;
|
||||
case EAST:
|
||||
GlStateManager.rotate(-90.0f, 0, 1, 0);
|
||||
GlStateManager.translate(0, 0, -1);
|
||||
break;
|
||||
case NORTH:
|
||||
break;
|
||||
case SOUTH:
|
||||
GlStateManager.rotate(180.0f, 0, 1, 0);
|
||||
GlStateManager.translate(-1, 0, -1);
|
||||
break;
|
||||
case UP:
|
||||
GlStateManager.translate(0, 1, 0);
|
||||
GlStateManager.rotate(90.0f, 1, 0, 0);
|
||||
break;
|
||||
case WEST:
|
||||
GlStateManager.translate(0, 0, 1);
|
||||
GlStateManager.rotate(90.0f, 0, 1, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translate(0.5f, 0.5f, getVerticalOffset(craftTime));
|
||||
// GlStateManager.rotate(rotation.getHorizontalAngle() + 180, 0, 0, 1);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
double topHeightOffset = 0;
|
||||
double middleHeightOffset = 0;
|
||||
double bottomHeightOffset = 0;
|
||||
|
||||
BlockPos pos = tileArray.getPos();
|
||||
World world = tileArray.getWorld();
|
||||
|
||||
// GlStateManager.rotate((float) (yaw + 360 * getStartupPitchYawRatio(craftTime)), 0, 0, 1);
|
||||
// GlStateManager.rotate((float) ((pitch + 90) * getStartupPitchYawRatio(craftTime)), 1, 0, 0);
|
||||
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
GlStateManager.pushMatrix();
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(bottomArrayResource);
|
||||
translateAndRotateFloatingArray(tessellator, wr, size, rot, craftTime, i);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
//Render the main array.
|
||||
GlStateManager.pushMatrix();
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(arrayResource);
|
||||
// GlStateManager.rotate(rot, 0, 0, 1);
|
||||
renderStandardCircle(tessellator, wr, 3);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
//Render the swirlz
|
||||
float swirlSize = 3;
|
||||
if (craftTime <= 40)
|
||||
{
|
||||
swirlSize = 0;
|
||||
} else if (craftTime <= 100)
|
||||
{
|
||||
swirlSize = 3 * (craftTime - 40) / 60;
|
||||
}
|
||||
GlStateManager.pushMatrix();
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(mobSacrificeSwirlResource);
|
||||
GlStateManager.translate(0, 0, 0.1);
|
||||
GlStateManager.rotate(rot / 3, 0, 0, 1);
|
||||
renderStandardCircle(tessellator, wr, swirlSize);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
// GlStateManager.popMatrix();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
// GlStateManager.depthMask(true);
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableCull();
|
||||
// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
public float getStartupPitchYawRatio(float craftTime)
|
||||
{
|
||||
if (craftTime <= 80)
|
||||
{
|
||||
return 0;
|
||||
} else if (craftTime > 80 && craftTime < 140)
|
||||
{
|
||||
return (craftTime - 80) / 60f;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void translateAndRotateFloatingArray(Tessellator tessellator, BufferBuilder builder, double size, float rotation, float craftTime, int circle)
|
||||
{
|
||||
double verticalOffset = 2;
|
||||
|
||||
float primaryRotation = 0;
|
||||
float secondaryRotation = 0;
|
||||
if (craftTime >= 40)
|
||||
{
|
||||
primaryRotation = (craftTime - 40) * 4f;
|
||||
secondaryRotation = (craftTime - 40) * 2f;
|
||||
}
|
||||
|
||||
float translationOffset = 1;
|
||||
if (craftTime < 80)
|
||||
{
|
||||
translationOffset = 0;
|
||||
} else if (craftTime < 140)
|
||||
{
|
||||
translationOffset = (craftTime - 80) / 60;
|
||||
}
|
||||
|
||||
switch (circle)
|
||||
{
|
||||
case 1:
|
||||
GlStateManager.translate(0, 0, -verticalOffset);
|
||||
GlStateManager.rotate(rotation / 200, 1, 0, 0);
|
||||
GlStateManager.rotate(rotation / 10, 0, 0, 1);
|
||||
GlStateManager.translate(1.7 * translationOffset, 0, 0);
|
||||
break;
|
||||
case 2:
|
||||
GlStateManager.translate(0, 0, -verticalOffset);
|
||||
// GlStateManager.rotate(254, 0, 0, 1);
|
||||
GlStateManager.rotate((float) (rotation / 150 + 120), 1, 0, 0);
|
||||
GlStateManager.rotate(120, 0, 1, 0);
|
||||
GlStateManager.rotate(-rotation / 10, 0, 0, 1);
|
||||
GlStateManager.translate(1.2 * translationOffset, 0, 0);
|
||||
break;
|
||||
case 3:
|
||||
GlStateManager.translate(0, 0, -verticalOffset);
|
||||
// GlStateManager.rotate(130, 0, 0, 1);
|
||||
GlStateManager.rotate((float) (rotation / 100 + 284), 1, 0, 0);
|
||||
GlStateManager.rotate(240, 0, 1, 0);
|
||||
GlStateManager.rotate(-rotation / 7 + 180, 0, 0, 1);
|
||||
GlStateManager.translate(2 * translationOffset, 0, 0);
|
||||
break;
|
||||
default:
|
||||
//What are you doing, Way???
|
||||
}
|
||||
|
||||
GlStateManager.rotate(primaryRotation, 0, 1, 0);
|
||||
GlStateManager.rotate(secondaryRotation, 1, 0, 0);
|
||||
GlStateManager.rotate(secondaryRotation * 0.41831f, 0, 0, 1);
|
||||
|
||||
renderStandardCircle(tessellator, builder, size);
|
||||
}
|
||||
|
||||
private void renderStandardCircle(Tessellator tessellator, BufferBuilder builder, double size)
|
||||
{
|
||||
double var31 = 0.0D;
|
||||
double var33 = 1.0D;
|
||||
double var35 = 0;
|
||||
double var37 = 1;
|
||||
GlStateManager.color(1f, 1f, 1f, 1f);
|
||||
builder.begin(7, DefaultVertexFormats.POSITION_TEX);
|
||||
// wr.setBrightness(200);
|
||||
builder.pos(size / 2f, size / 2f, 0).tex(var33, var37).endVertex();
|
||||
builder.pos(size / 2f, -size / 2f, 0).tex(var33, var35).endVertex();
|
||||
builder.pos(-size / 2f, -size / 2f, 0).tex(var31, var35).endVertex();
|
||||
builder.pos(-size / 2f, size / 2f, 0).tex(var31, var37).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
}
|
|
@ -237,4 +237,9 @@ public class RegistrarBloodMagicRecipes
|
|||
registrar.addAlchemyArray(ComponentTypes.REAGENT_FROST.getStack(), ItemSlate.SlateType.REINFORCED.getStack(), new ItemStack(RegistrarBloodMagicItems.SIGIL_FROST), null);
|
||||
|
||||
}
|
||||
|
||||
public static void registerSacrificeCraftRecipes(BloodMagicRecipeRegistrar registrar)
|
||||
{
|
||||
registrar.addSacrificeCraft(new ItemStack(RegistrarBloodMagicBlocks.TELEPOSER), 10, Items.REDSTONE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectBinding;
|
|||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectBounce;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectFurnaceFuel;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectLaputa;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectMobSacrifice;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectMovement;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectSigil;
|
||||
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectSkeletonTurret;
|
||||
|
@ -36,6 +37,7 @@ import WayofTime.bloodmagic.client.render.alchemyArray.BindingAlchemyCircleRende
|
|||
import WayofTime.bloodmagic.client.render.alchemyArray.DualAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.LowAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.LowStaticAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.MobSacrificeAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.SingleAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.StaticAlchemyCircleRenderer;
|
||||
import WayofTime.bloodmagic.client.render.alchemyArray.TurretAlchemyCircleRenderer;
|
||||
|
@ -128,6 +130,7 @@ public class ModRecipes
|
|||
AlchemyArrayRecipeRegistry.registerRecipe(new ItemStack(Items.BOW), new ItemStack(Items.ARROW), new AlchemyArrayEffectArrowTurret("turret"), new TurretAlchemyCircleRenderer(new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/SkeletonTurret1.png")));
|
||||
AlchemyArrayRecipeRegistry.registerRecipe(new ItemStack(Items.REDSTONE), new ItemStack(Blocks.LAPIS_BLOCK), new AlchemyArrayEffectLaputa("laputa"), new AttractorAlchemyCircleRenderer(new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/shardoflaputa.png")));
|
||||
AlchemyArrayRecipeRegistry.registerRecipe(new ItemStack(Blocks.COBBLESTONE), new ItemStack(Items.IRON_INGOT), new AlchemyArrayEffectSpike("spike"), new LowStaticAlchemyCircleRenderer(new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/spikearray.png")));
|
||||
AlchemyArrayRecipeRegistry.registerRecipe(new ItemStack(Blocks.REDSTONE_BLOCK), new ItemStack(Items.REDSTONE), new AlchemyArrayEffectMobSacrifice("mobSacrifice"), new MobSacrificeAlchemyCircleRenderer());
|
||||
|
||||
AlchemyArrayRecipeRegistry.registerRecipe(ComponentTypes.REAGENT_FAST_MINER.getStack(), new ItemStack(Items.IRON_PICKAXE), new AlchemyArrayEffectSigil("fastMiner", (ISigil) RegistrarBloodMagicItems.SIGIL_FAST_MINER), new SingleAlchemyCircleRenderer(new ResourceLocation("bloodmagic", "textures/models/AlchemyArrays/FastMinerSigil.png")));
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
Loading…
Reference in a new issue