New commit

This commit is contained in:
WayofTime 2014-06-21 18:47:00 -04:00
parent 184f4bb85d
commit a9c857bbcb
11 changed files with 1683 additions and 0 deletions

View file

@ -0,0 +1,227 @@
package WayofTime.alchemicalWizardry.api.items;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import WayofTime.alchemicalWizardry.api.items.interfaces.IBloodOrb;
/** Shaped Blood Orb Recipe Handler by joshie **/
public class ShapedBloodOrbRecipe implements IRecipe {
private static final int MAX_CRAFT_GRID_WIDTH = 3;
private static final int MAX_CRAFT_GRID_HEIGHT = 3;
private ItemStack output = null;
private Object[] input = null;
public int width = 0;
public int height = 0;
private boolean mirrored = true;
public ShapedBloodOrbRecipe(Block result, Object... recipe) {
this(new ItemStack(result), recipe);
}
public ShapedBloodOrbRecipe(Item result, Object... recipe) {
this(new ItemStack(result), recipe);
}
public ShapedBloodOrbRecipe(ItemStack result, Object... recipe) {
output = result.copy();
String shape = "";
int idx = 0;
if (recipe[idx] instanceof Boolean) {
mirrored = (Boolean) recipe[idx];
if (recipe[idx + 1] instanceof Object[]) {
recipe = (Object[]) recipe[idx + 1];
} else {
idx = 1;
}
}
if (recipe[idx] instanceof String[]) {
String[] parts = ((String[]) recipe[idx++]);
for (String s : parts) {
width = s.length();
shape += s;
}
height = parts.length;
} else {
while (recipe[idx] instanceof String) {
String s = (String) recipe[idx++];
shape += s;
width = s.length();
height++;
}
}
if (width * height != shape.length()) {
String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe) {
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
HashMap<Character, Object> itemMap = new HashMap<Character, Object>();
for (; idx < recipe.length; idx += 2) {
Character chr = (Character) recipe[idx];
Object in = recipe[idx + 1];
if (in instanceof IBloodOrb || (in instanceof ItemStack && ((ItemStack)in).getItem() instanceof IBloodOrb)) { //If the item is an instanceof IBloodOrb then save the level of the orb
if(in instanceof ItemStack) itemMap.put(chr, (Integer)(((IBloodOrb)((ItemStack)in).getItem()).getOrbLevel()));
else itemMap.put(chr, (Integer)(((IBloodOrb)in).getOrbLevel()));
} else if (in instanceof ItemStack) {
itemMap.put(chr, ((ItemStack) in).copy());
} else if (in instanceof Item) {
itemMap.put(chr, new ItemStack((Item) in));
} else if (in instanceof Block) {
itemMap.put(chr, new ItemStack((Block) in, 1, OreDictionary.WILDCARD_VALUE));
} else if (in instanceof String) {
itemMap.put(chr, OreDictionary.getOres((String) in));
} else {
String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe) {
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
}
input = new Object[width * height];
int x = 0;
for (char chr : shape.toCharArray()) {
input[x++] = itemMap.get(chr);
}
}
ShapedBloodOrbRecipe(ShapedRecipes recipe, Map<ItemStack, String> replacements) {
output = recipe.getRecipeOutput();
width = recipe.recipeWidth;
height = recipe.recipeHeight;
input = new Object[recipe.recipeItems.length];
for (int i = 0; i < input.length; i++) {
ItemStack ingred = recipe.recipeItems[i];
if (ingred == null)
continue;
input[i] = recipe.recipeItems[i];
for (Entry<ItemStack, String> replace : replacements.entrySet()) {
if (OreDictionary.itemMatches(replace.getKey(), ingred, true)) {
input[i] = OreDictionary.getOres(replace.getValue());
break;
}
}
}
}
@Override
public ItemStack getCraftingResult(InventoryCrafting var1) {
return output.copy();
}
@Override
public int getRecipeSize() {
return input.length;
}
@Override
public ItemStack getRecipeOutput() {
return output;
}
@Override
public boolean matches(InventoryCrafting inv, World world) {
for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++) {
for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y) {
if (checkMatch(inv, x, y, false)) {
return true;
}
if (mirrored && checkMatch(inv, x, y, true)) {
return true;
}
}
}
return false;
}
@SuppressWarnings("unchecked")
private boolean checkMatch(InventoryCrafting inv, int startX, int startY, boolean mirror) {
for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++) {
for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++) {
int subX = x - startX;
int subY = y - startY;
Object target = null;
if (subX >= 0 && subY >= 0 && subX < width && subY < height) {
if (mirror) {
target = input[width - subX - 1 + subY * width];
} else {
target = input[subX + subY * width];
}
}
ItemStack slot = inv.getStackInRowAndColumn(x, y);
//If target is integer, then we should be check the blood orb value of the item instead
if(target instanceof Integer) {
if(slot != null && slot.getItem() instanceof IBloodOrb) {
IBloodOrb orb = (IBloodOrb) slot.getItem();
if(orb.getOrbLevel() < (Integer)target) {
return false;
}
} else return false;
} else if (target instanceof ItemStack) {
if (!OreDictionary.itemMatches((ItemStack) target, slot, false)) {
return false;
}
} else if (target instanceof ArrayList) {
boolean matched = false;
Iterator<ItemStack> itr = ((ArrayList<ItemStack>) target).iterator();
while (itr.hasNext() && !matched) {
matched = OreDictionary.itemMatches(itr.next(), slot, false);
}
if (!matched) {
return false;
}
} else if (target == null && slot != null) {
return false;
}
}
}
return true;
}
public ShapedBloodOrbRecipe setMirrored(boolean mirror) {
mirrored = mirror;
return this;
}
public Object[] getInput() {
return this.input;
}
}

View file

@ -0,0 +1,140 @@
package WayofTime.alchemicalWizardry.api.items;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.ShapelessRecipes;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import WayofTime.alchemicalWizardry.api.items.interfaces.IBloodOrb;
/** Shapeless Blood Orb Recipe Handler by joshie **/
public class ShapelessBloodOrbRecipe implements IRecipe {
private ItemStack output = null;
private ArrayList<Object> input = new ArrayList<Object>();
public ShapelessBloodOrbRecipe(Block result, Object... recipe) {
this(new ItemStack(result), recipe);
}
public ShapelessBloodOrbRecipe(Item result, Object... recipe) {
this(new ItemStack(result), recipe);
}
public ShapelessBloodOrbRecipe(ItemStack result, Object... recipe) {
output = result.copy();
for (Object in : recipe) {
if (in instanceof ItemStack) {
input.add(((ItemStack) in).copy());
} else if (in instanceof IBloodOrb) { //If the item is an instanceof IBloodOrb then save the level of the orb
input.add((Integer)(((IBloodOrb)in).getOrbLevel()));
} else if (in instanceof Item) {
input.add(new ItemStack((Item) in));
} else if (in instanceof Block) {
input.add(new ItemStack((Block) in));
} else if (in instanceof String) {
input.add(OreDictionary.getOres((String) in));
} else {
String ret = "Invalid shapeless ore recipe: ";
for (Object tmp : recipe) {
ret += tmp + ", ";
}
ret += output;
throw new RuntimeException(ret);
}
}
}
@SuppressWarnings("unchecked")
ShapelessBloodOrbRecipe(ShapelessRecipes recipe, Map<ItemStack, String> replacements) {
output = recipe.getRecipeOutput();
for (ItemStack ingred : ((List<ItemStack>) recipe.recipeItems)) {
Object finalObj = ingred;
for (Entry<ItemStack, String> replace : replacements.entrySet()) {
if (OreDictionary.itemMatches(replace.getKey(), ingred, false)) {
finalObj = OreDictionary.getOres(replace.getValue());
break;
}
}
input.add(finalObj);
}
}
@Override
public int getRecipeSize() {
return input.size();
}
@Override
public ItemStack getRecipeOutput() {
return output;
}
@Override
public ItemStack getCraftingResult(InventoryCrafting var1) {
return output.copy();
}
@SuppressWarnings("unchecked")
@Override
public boolean matches(InventoryCrafting var1, World world) {
ArrayList<Object> required = new ArrayList<Object>(input);
for (int x = 0; x < var1.getSizeInventory(); x++) {
ItemStack slot = var1.getStackInSlot(x);
if (slot != null) {
boolean inRecipe = false;
Iterator<Object> req = required.iterator();
while (req.hasNext()) {
boolean match = false;
Object next = req.next();
//If target is integer, then we should be check the blood orb value of the item instead
if(next instanceof Integer) {
if(slot != null && slot.getItem() instanceof IBloodOrb) {
IBloodOrb orb = (IBloodOrb) slot.getItem();
if(orb.getOrbLevel() < (Integer)next) {
return false;
}
} else return false;
} else if (next instanceof ItemStack) {
match = OreDictionary.itemMatches((ItemStack) next, slot, false);
} else if (next instanceof ArrayList) {
Iterator<ItemStack> itr = ((ArrayList<ItemStack>) next).iterator();
while (itr.hasNext() && !match) {
match = OreDictionary.itemMatches(itr.next(), slot, false);
}
}
if (match) {
inRecipe = true;
required.remove(next);
break;
}
}
if (!inRecipe) {
return false;
}
}
}
return required.isEmpty();
}
public ArrayList<Object> getInput() {
return this.input;
}
}

View file

@ -0,0 +1,16 @@
package WayofTime.alchemicalWizardry.common;
public class Int3
{
public int xCoord;
public int yCoord;
public int zCoord;
public Int3(int xCoord, int yCoord, int zCoord)
{
this.xCoord = xCoord;
this.yCoord = yCoord;
this.zCoord = zCoord;
}
}

View file

@ -0,0 +1,43 @@
package WayofTime.alchemicalWizardry.common.block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import WayofTime.alchemicalWizardry.AlchemicalWizardry;
import WayofTime.alchemicalWizardry.common.tileEntity.TEAltar;
import WayofTime.alchemicalWizardry.common.tileEntity.TEDemonPortal;
public class BlockDemonPortal extends BlockContainer
{
public BlockDemonPortal()
{
super(Material.rock);
setHardness(2.0F);
setResistance(5.0F);
setCreativeTab(AlchemicalWizardry.tabBloodMagic);
this.setBlockName("demonPortal");
}
@Override
public TileEntity createNewTileEntity(World var1, int var2)
{
return new TEDemonPortal();
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float what, float these, float are)
{
if(world.isRemote)
{
return false;
}
TEDemonPortal tileEntity = (TEDemonPortal) world.getTileEntity(x, y, z);
tileEntity.rightClickBlock(player, side);
return false;
}
}

View file

@ -0,0 +1,150 @@
package WayofTime.alchemicalWizardry.common.demonVillage;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import WayofTime.alchemicalWizardry.common.Int3;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
public class BlockSet
{
private String blockid;
private int[] metadata;
private List<Int3> positions;
public BlockSet()
{
this(Blocks.stone);
}
public BlockSet(String blockid)
{
this.blockid = blockid;
this.metadata = new int[4];
positions = new ArrayList();
}
public BlockSet(Block block)
{
this(BlockSet.getPairedIdForBlock(block));
}
public BlockSet(Block block, int meta)
{
this(block);
for(int i=0; i<metadata.length; i++)
{
metadata[i] = meta;
}
}
public void addPositionToBlock(int xOffset, int yOffset, int zOffset)
{
positions.add(new Int3(xOffset, yOffset, zOffset));
}
public Block getBlock()
{
return this.getBlockForString(blockid);
}
public static String getPairedIdForBlock(Block block)
{
UniqueIdentifier un = GameRegistry.findUniqueIdentifierFor(block);
String name = "";
if(un != null)
{
name = un.modId + ":" + un.name;
}
return name;
}
public static Block getBlockForString(String str)
{
String[] parts = str.split(":");
String modId = parts[0];
String name = parts[1];
return GameRegistry.findBlock(modId, name);
}
public int getMetaForDirection(ForgeDirection dir)
{
if(metadata.length < 4)
{
return 0;
}
switch(dir)
{
case NORTH:
return metadata[0];
case SOUTH:
return metadata[1];
case WEST:
return metadata[2];
case EAST:
return metadata[3];
default:
return 0;
}
}
public void buildAtIndex(World world, int xCoord, int yCoord, int zCoord, ForgeDirection dir, int index)
{
Block block = this.getBlock();
if(index >= positions.size() || block == null)
{
return;
}
Int3 position = positions.get(index);
int xOff = position.xCoord;
int yOff = position.yCoord;
int zOff = position.zCoord;
int meta = this.getMetaForDirection(dir);
switch(dir)
{
case NORTH:
break;
case SOUTH:
xOff *= -1;
yOff *= -1;
break;
case WEST:
int temp = zOff;
zOff = xOff * -1;
xOff = temp;
break;
case EAST:
int temp2 = zOff * -1;
zOff = xOff;
xOff = temp2;
break;
default:
}
world.setBlock(xCoord + xOff, yCoord + yOff, zCoord + zOff, block, meta, 3);
}
public void buildAll(World world, int xCoord, int yCoord, int zCoord, ForgeDirection dir)
{
for(int i=0; i<positions.size(); i++)
{
this.buildAtIndex(world, xCoord, yCoord, zCoord, dir, i);
}
}
public boolean isContained(Block block, int defaultMeta)
{
Block thisBlock = this.getBlock();
return thisBlock == null ? false : thisBlock.equals(block) && this.metadata[0] == defaultMeta;
}
}

View file

@ -0,0 +1,45 @@
package WayofTime.alchemicalWizardry.common.demonVillage;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.world.World;
public class BuildingSchematic
{
public String name;
public List<BlockSet> blockList;
public BuildingSchematic()
{
this("");
}
public BuildingSchematic(String name)
{
this.name = name;
blockList = new ArrayList();
}
public void addBlockWithMeta(Block block, int meta, int xOffset, int yOffset, int zOffset)
{
for(BlockSet set : blockList)
{
if(set.isContained(block, meta))
{
set.addPositionToBlock(xOffset, yOffset, zOffset);
return;
}
}
BlockSet set = new BlockSet(block, meta);
set.addPositionToBlock(xOffset, yOffset, zOffset);
blockList.add(set);
}
public void buildAll(World world, int xCoord, int yCoord, int zCoord)
{
}
}

View file

@ -0,0 +1,22 @@
package WayofTime.alchemicalWizardry.common.demonVillage;
import net.minecraft.world.World;
public class DemonCrosspath
{
private int xCoord;
private int yLevel;
private int zCoord;
public DemonCrosspath(int xCoord, int yLevel, int zCoord)
{
this.xCoord = xCoord;
this.yLevel = yLevel;
this.zCoord = zCoord;
}
public void createCrosspath(World world)
{
}
}

View file

@ -0,0 +1,133 @@
package WayofTime.alchemicalWizardry.common.demonVillage;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import WayofTime.alchemicalWizardry.ModBlocks;
import WayofTime.alchemicalWizardry.common.Int3;
public class DemonVillagePath
{
public int xi;
public int yi;
public int zi;
public ForgeDirection dir;
public int length;
public DemonVillagePath(int xi, int yi, int zi, ForgeDirection dir, int length)
{
this.xi = xi;
this.yi = yi;
this.zi = zi;
this.dir = dir;
this.length = length;
}
public Int3 constructFullPath(World world, int clearance, Block block, int meta)
{
int xPos = this.xi;
int yPos = this.yi;
int zPos = this.zi;
int rad = this.getRoadRadius();
for(int i=-rad; i<=rad; i++)
{
this.constructPartialPath(world, clearance, block, meta, xPos-rad*dir.offsetX+i*dir.offsetZ, yPos, zPos-rad*dir.offsetZ+i*dir.offsetX, dir, length+2*rad);
}
return this.getFinalLocation(world, clearance);
}
public void constructPartialPath(World world, int clearance, Block roadBlock, int meta, int xi, int yi, int zi, ForgeDirection dir, int length)
{
int xPos = xi;
int yPos = yi;
int zPos = zi;
for(int i=0; i<length; i++)
{
int xOffset = i*dir.offsetX;
int zOffset = i*dir.offsetZ;
for(int yOffset=0; yOffset<=clearance; yOffset++)
{
int sign = 1;
Block block1 = world.getBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset);
Block highBlock1 = world.getBlock(xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset);
if(!block1.isReplaceable(world, xPos + xOffset, yPos + sign*yOffset, zPos + zOffset) && this.isBlockReplaceable(block1) && highBlock1.isReplaceable(world, xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset))
{
world.setBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset, roadBlock, meta, 3);
yPos += sign*yOffset;
break;
}else
{
sign = -1;
Block block2 = world.getBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset);
Block highBlock2 = world.getBlock(xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset);
if(!block2.isReplaceable(world, xPos + xOffset, yPos + sign*yOffset, zPos + zOffset) && this.isBlockReplaceable(block1) && highBlock2.isReplaceable(world, xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset))
{
world.setBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset, roadBlock, meta, 3);
yPos += sign*yOffset;
break;
}
}
}
}
}
public Int3 getFinalLocation(World world, int clearance)
{
int xPos = xi;
int yPos = yi;
int zPos = zi;
for(int i=0; i<length; i++)
{
int xOffset = i*dir.offsetX;
int zOffset = i*dir.offsetZ;
for(int yOffset=0; yOffset<=clearance; yOffset++)
{
int sign = 1;
Block block1 = world.getBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset);
if(!world.isAirBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset) && this.isBlockReplaceable(block1) && world.isAirBlock(xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset))
{
yPos += sign*yOffset;
break;
}else
{
sign = -1;
Block block2 = world.getBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset);
if(!world.isAirBlock(xPos + xOffset, yPos + sign*yOffset, zPos + zOffset) && this.isBlockReplaceable(block2) && world.isAirBlock(xPos + xOffset, yPos + sign*yOffset + 1, zPos + zOffset))
{
yPos += sign*yOffset;
break;
}
}
}
}
return new Int3(xi,yi,zi);
}
public int getRoadRadius()
{
return 1;
}
public boolean isBlockReplaceable(Block block)
{
if(block.getMaterial() == Material.leaves || block.getMaterial() == Material.vine)
{
return false;
}
return !block.equals(ModBlocks.blockDemonPortal);
}
}

View file

@ -0,0 +1,72 @@
package WayofTime.alchemicalWizardry.common.demonVillage;
import net.minecraft.nbt.NBTTagCompound;
public class GridSpace
{
public static final int EMPTY = 0;
public static final int MAIN_PORTAL = 1;
public static final int MINI_PORTAL = 2;
public static final int ROAD = 3;
public static final int CROSSROAD = 4;
public static final int HOUSE = 5;
private int yLevel;
private int type;
public GridSpace()
{
this(EMPTY, -1);
}
public GridSpace(int type, int yLevel)
{
this.type = type;
this.yLevel = yLevel;
}
public int getGridType()
{
return this.type;
}
public void setGridType(int type)
{
this.type = type;
}
public int getYLevel()
{
return this.yLevel;
}
public void setYLevel(int yLevel)
{
this.yLevel = yLevel;
}
public boolean isEmpty()
{
return type == this.EMPTY;
}
public static GridSpace getGridFromTag(NBTTagCompound tag)
{
return new GridSpace(tag.getInteger("type"), tag.getInteger("yLevel"));
}
public NBTTagCompound getTag()
{
NBTTagCompound tag = new NBTTagCompound();
tag.setInteger("type", type);
tag.setInteger("yLevel", yLevel);
return tag;
}
public boolean isRoadSegment()
{
return type == this.ROAD || type == this.CROSSROAD;
}
}

View file

@ -0,0 +1,654 @@
package WayofTime.alchemicalWizardry.common.tileEntity;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import WayofTime.alchemicalWizardry.ModBlocks;
import WayofTime.alchemicalWizardry.common.Int3;
import WayofTime.alchemicalWizardry.common.demonVillage.BuildingSchematic;
import WayofTime.alchemicalWizardry.common.demonVillage.DemonCrosspath;
import WayofTime.alchemicalWizardry.common.demonVillage.DemonVillagePath;
import WayofTime.alchemicalWizardry.common.demonVillage.GridSpace;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class TEDemonPortal extends TileEntity
{
public static List<BuildingSchematic> buildingList = new ArrayList();
public Random rand = new Random();
private GridSpace[][] area;
private int negXRadius; //These variables indicate how much the grid has expanded from the 1x1
private int posXRadius; //matrix in each direction
private int negZRadius;
private int posZRadius;
private boolean isInitialized;
public TEDemonPortal()
{
super();
negXRadius = posXRadius = negZRadius = posZRadius = 1;
area = new GridSpace[negXRadius + posXRadius + 1][negZRadius + posZRadius + 1];
for(int xIndex = -negXRadius; xIndex <= posXRadius; xIndex++)
{
for(int zIndex = -negZRadius; zIndex <= posZRadius; zIndex++)
{
if(Math.abs(xIndex) == 1 || Math.abs(zIndex) == 1)
{
this.setGridSpace(xIndex, zIndex, new GridSpace(GridSpace.ROAD,4));
}else
{
this.setGridSpace(xIndex, zIndex, new GridSpace());
}
}
}
isInitialized = false;
this.setGridSpace(0, 0, new GridSpace(GridSpace.MAIN_PORTAL, yCoord));
}
public void initialize()
{
if(isInitialized)
{
return;
}
for(int xIndex = -negXRadius; xIndex <= posXRadius; xIndex++)
{
for(int zIndex = -negZRadius; zIndex <= posZRadius; zIndex++)
{
if(Math.abs(xIndex) == 1 || Math.abs(zIndex) == 1)
{
this.setGridSpace(xIndex, zIndex, new GridSpace(GridSpace.ROAD,yCoord));
}else
{
this.setGridSpace(xIndex, zIndex, new GridSpace());
}
}
}
isInitialized = true;
}
@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
super.readFromNBT(par1NBTTagCompound);
this.negXRadius = par1NBTTagCompound.getInteger("negXRadius");
this.negZRadius = par1NBTTagCompound.getInteger("negZRadius");
this.posXRadius = par1NBTTagCompound.getInteger("posXRadius");
this.posZRadius = par1NBTTagCompound.getInteger("posZRadius");
area = new GridSpace[negXRadius + posXRadius + 1][negZRadius + posZRadius + 1];
NBTTagList tagList = par1NBTTagCompound.getTagList("Grid",Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < tagList.tagCount(); i++)
{
int length = (negZRadius+posZRadius+1);
int x = i/length;
int z = i%length;
NBTTagCompound tag = (NBTTagCompound) tagList.getCompoundTagAt(i);
GridSpace space = GridSpace.getGridFromTag(tag);
area[x][z] = space;
}
this.isInitialized = par1NBTTagCompound.getBoolean("init");
}
@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeToNBT(par1NBTTagCompound);
par1NBTTagCompound.setInteger("negXRadius", negXRadius);
par1NBTTagCompound.setInteger("negZRadius", negZRadius);
par1NBTTagCompound.setInteger("posXRadius", posXRadius);
par1NBTTagCompound.setInteger("posZRadius", posZRadius);
NBTTagList gridList = new NBTTagList();
for(int i=0; i<=negXRadius+posXRadius; i++)
{
for(int j=0; j<=negZRadius+posZRadius; j++)
{
int index = i + (negZRadius+posZRadius+1)*j;
GridSpace space = area[i][j];
NBTTagCompound nextTag;
if(space == null)
{
nextTag = new GridSpace().getTag();
}else
{
nextTag = space.getTag();
}
gridList.appendTag(nextTag);
}
}
par1NBTTagCompound.setTag("Grid", gridList);
par1NBTTagCompound.setBoolean("init", isInitialized);
}
public void createRandomRoad()
{
int next = rand.nextInt(4);
ForgeDirection dir;
switch(next)
{
case 0:
dir = ForgeDirection.NORTH;
break;
case 1:
dir = ForgeDirection.SOUTH;
break;
case 2:
dir = ForgeDirection.EAST;
break;
case 3:
dir = ForgeDirection.WEST;
break;
default:
dir = ForgeDirection.NORTH;
}
int length = 5;
Int3 road = findRoadSpaceFromDirection(dir, (rand.nextInt(negXRadius + negZRadius + posXRadius + posZRadius))+1);
int x = road.xCoord;
int yLevel = road.yCoord;
int z = road.zCoord;
System.out.println("X: " + x + " Z: " + z + " Direction: " + dir.toString());
List<ForgeDirection> directions = this.findValidExtentionDirection(x, z);
if(directions.size() <= 0)
{
return;
}
int maxDistance = 5;
int distance = 0;
ForgeDirection dominantDirection = null;
for(ForgeDirection direction: directions)
{
int amt = this.getLength(direction, maxDistance, x, z);
if(amt > distance)
{
distance = amt;
dominantDirection = direction;
}else if(amt == distance && rand.nextBoolean())
{
dominantDirection = direction;
}
}
if(dominantDirection == null)
{
return;
}
System.out.println("I got here!");
System.out.println("Distance: " + distance + " Direction: " + dominantDirection.toString() + " yLevel: " + yLevel);
this.createGriddedRoad(x, yLevel, z, dominantDirection, distance+1, true);
}
public List<ForgeDirection> findValidExtentionDirection(int x, int z)
{
List<ForgeDirection> directions = new LinkedList();
if(this.getGridSpace(x, z) == null || !this.getGridSpace(x, z).isRoadSegment())
{
return directions;
}
GridSpace nextGrid = this.getGridSpace(x+1, z);
if(nextGrid.isEmpty())
{
directions.add(ForgeDirection.EAST);
}
nextGrid = this.getGridSpace(x-1, z);
if(nextGrid.isEmpty())
{
directions.add(ForgeDirection.WEST);
}
nextGrid = this.getGridSpace(x, z+1);
if(nextGrid.isEmpty())
{
directions.add(ForgeDirection.SOUTH);
}
nextGrid = this.getGridSpace(x, z-1);
if(nextGrid.isEmpty())
{
directions.add(ForgeDirection.NORTH);
}
return directions;
}
public int getLength(ForgeDirection dir, int maxLength, int x, int z) //Number of spaces forward
{
for(int i=1; i<=maxLength; i++)
{
GridSpace space = this.getGridSpace(x + i*dir.offsetX, z + i*dir.offsetZ);
if(space.isEmpty())
{
for(int k=1; k<=this.getRoadSpacer(); k++)
{
GridSpace space1 = this.getGridSpace(x + i*dir.offsetX + dir.offsetZ*k, z + i*dir.offsetZ + dir.offsetX*k);
GridSpace space2 = this.getGridSpace(x + i*dir.offsetX - dir.offsetZ*k, z + i*dir.offsetZ - dir.offsetX*k);
if(space1.isRoadSegment() || space2.isRoadSegment())
{
return i-1;
}
}
continue;
}
if(space.isRoadSegment())
{
return i;
}else
{
return i-1;
}
}
return maxLength;
}
public Int3 findRoadSpaceFromDirection(ForgeDirection dir, int amount)
{
int index = 0;
if(dir == ForgeDirection.NORTH)
{
System.out.print("NORTH!");
for(int i=0; i<= negZRadius + posZRadius; i++)
{
for(int j=0; j<= negXRadius + posXRadius; j++)
{
GridSpace space = area[j][i];
if(space.isRoadSegment())
{
index++;
if(index >= amount)
{
return new Int3(j-negXRadius,space.getYLevel(),i-negZRadius);
}
}
}
}
}else if(dir == ForgeDirection.SOUTH)
{
for(int i=negZRadius + posZRadius; i >= 0 ; i--)
{
for(int j=0; j<= negXRadius + posXRadius; j++)
{
GridSpace space = area[j][i];
if(space.isRoadSegment())
{
index++;
if(index >= amount)
{
return new Int3(j-negXRadius,space.getYLevel(),i-negZRadius);
}
}
}
}
}else if(dir == ForgeDirection.EAST)
{
for(int i=negXRadius + posXRadius; i >= 0; i--)
{
for(int j=0; j <= negZRadius + posZRadius ; j++)
{
GridSpace space = area[i][j];
if(space.isRoadSegment())
{
index++;
if(index >= amount)
{
return new Int3(i-negXRadius,space.getYLevel(),j-negZRadius);
}
}
}
}
}else if(dir == ForgeDirection.WEST)
{
for(int i=0; i <= negXRadius + posXRadius; i++)
{
for(int j=0; j <= negZRadius + posZRadius ; j++)
{
GridSpace space = area[i][j];
if(space.isRoadSegment())
{
index++;
if(index >= amount)
{
return new Int3(i-negXRadius,space.getYLevel(),j-negZRadius);
}
}
}
}
}
return new Int3(0,0,0);
}
public void createGriddedRoad(int gridXi, int yi, int gridZi, ForgeDirection dir, int gridLength, boolean convertStarter) //Total grid length
{
if(gridLength == 0 || gridLength == 1)
{
return;
}
if(convertStarter)
{
}
int initGridX = gridXi;
int initGridZ = gridZi;
int initY = yi;
if(convertStarter)
{
this.setGridSpace(initGridX, initGridZ, new GridSpace(GridSpace.CROSSROAD,initY));
DemonCrosspath crosspath = new DemonCrosspath(xCoord + initGridX*5, initY, zCoord + initGridZ*5);
crosspath.createCrosspath(worldObj);
}
for(int index=0; index<gridLength-1; index++)
{
DemonVillagePath path = new DemonVillagePath(xCoord + initGridX*5, initY, zCoord + initGridZ*5, dir, 6);
Int3 next = path.constructFullPath(worldObj, this.getRoadStepClearance(), this.getRoadBlock(), this.getRoadMeta());
if(next != null)
{
initY = next.yCoord;
}
initGridX += dir.offsetX;
initGridZ += dir.offsetZ;
if(!this.getGridSpace(initGridX, initGridZ).isRoadSegment())
{
this.setGridSpace(initGridX, initGridZ, new GridSpace(GridSpace.ROAD,initY));
}
}
}
public void expandAreaInNegX()
{
GridSpace[][] newGrid = new GridSpace[negXRadius + posXRadius + 2][negZRadius + posZRadius + 1];
for(int i=0; i<=negZRadius + posZRadius; i++)
{
newGrid[0][i] = new GridSpace();
}
for(int i=0; i<=negXRadius + posXRadius; i++)
{
for(int j=0; j<=negZRadius + posZRadius; j++)
{
newGrid[i+1][j] = area[i][j];
}
}
area = newGrid;
negXRadius += 1;
}
public void expandAreaInPosX()
{
GridSpace[][] newGrid = new GridSpace[negXRadius + posXRadius + 2][negZRadius + posZRadius + 1];
for(int i=0; i<=negZRadius + posZRadius; i++)
{
newGrid[negXRadius + posXRadius + 1][i] = new GridSpace();
}
for(int i=0; i<=negXRadius + posXRadius; i++)
{
for(int j=0; j<=negZRadius + posZRadius; j++)
{
newGrid[i][j] = area[i][j];
}
}
area = newGrid;
posXRadius += 1;
}
public void expandAreaInNegZ()
{
GridSpace[][] newGrid = new GridSpace[negXRadius + posXRadius + 1][negZRadius + posZRadius + 2];
System.out.println("x " + newGrid.length + "z " + newGrid[0].length);
for(int i=0; i<=negXRadius + posXRadius; i++)
{
newGrid[i][0] = new GridSpace();
}
for(int i=0; i<=negXRadius + posXRadius; i++)
{
for(int j=0; j<=negZRadius + posZRadius; j++)
{
newGrid[i][j+1] = area[i][j];
}
}
area = newGrid;
negZRadius += 1;
}
public void expandAreaInPosZ()
{
GridSpace[][] newGrid = new GridSpace[negXRadius + posXRadius + 1][negZRadius + posZRadius + 2];
for(int i=0; i<=negXRadius + posXRadius; i++)
{
newGrid[i][negZRadius + posZRadius + 1] = new GridSpace();
}
for(int i=0; i<=negXRadius + posXRadius; i++)
{
for(int j=0; j<=negZRadius + posZRadius; j++)
{
newGrid[i][j] = area[i][j];
}
}
area = newGrid;
posZRadius += 1;
}
public GridSpace getGridSpace(int x, int z)
{
if(x > posXRadius|| x < -negXRadius || z > posZRadius || z < -negZRadius)
{
return new GridSpace();
}else
{
return (area[x + negXRadius][z + negZRadius]);
}
}
public void setGridSpace(int x, int z, GridSpace space)
{
if(x > posXRadius)
{
this.expandAreaInPosX();
this.setGridSpace(x, z, space);
return;
}else if(x < -negXRadius)
{
this.expandAreaInNegX();
this.setGridSpace(x, z, space);
return;
}else if(z > posZRadius)
{
this.expandAreaInPosZ();
this.setGridSpace(x, z, space);
return;
}else if(z < -negZRadius)
{
this.expandAreaInNegZ();
this.setGridSpace(x, z, space);
return;
}else
{
area[x + negXRadius][z + negZRadius] = space;
}
}
public void rightClickBlock(EntityPlayer player, int side)
{
this.testGson();
Int3 roadMarker = this.getNextRoadMarker();
this.initialize();
this.createRandomRoad();
}
public void testGson()
{
boolean write = true;
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(new BuildingSchematic());
try {
if(write)
{
Writer writer = new FileWriter("config/test3.json");
writer.write(json);
writer.close();
}
{
BufferedReader br = new BufferedReader(new FileReader("config/test3.json"));
BuildingSchematic schema = gson.fromJson(br, BuildingSchematic.class);
String newJson = gson.toJson(schema);
Writer writer = new FileWriter("config/test4.json");
writer.write(newJson);
writer.close();
}
{
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void createRoad(int xi, int yi, int zi, ForgeDirection dir, int length, boolean doesNotDrop)
{
int curX = xi;
int curY = yi;
int curZ = zi;
int roadRadius = this.getRoadRadius();
if(dir.offsetY != 0)
{
return;
}
DemonVillagePath path = new DemonVillagePath(xi, yi, zi, dir, length);
path.constructFullPath(worldObj, this.getRoadStepClearance(), this.getRoadBlock(), this.getRoadMeta());
}
public int placeMaterialOnNextAvailable()
{
return 0;
}
public int getRoadRadius()
{
return 1;
}
public Block getRoadBlock()
{
return Blocks.nether_brick;
}
public int getRoadMeta()
{
return 0;
}
public int getRoadStepClearance()
{
return 10;
}
public Block getRoadMarker()
{
return ModBlocks.ritualStone;
}
public Int3 getNextRoadMarker()
{
int horizSearchMax = 25;
int vertSearchMax = 10;
for(int xPos=xCoord-horizSearchMax; xPos<=xCoord+horizSearchMax; xPos++)
{
for(int zPos=zCoord-horizSearchMax; zPos<=zCoord+horizSearchMax; zPos++)
{
for(int yPos=yCoord-vertSearchMax; yPos<=yCoord+vertSearchMax; yPos++)
{
Block block = worldObj.getBlock(xPos, yPos, zPos);
if(block == this.getRoadMarker())
{
return new Int3(xPos,yPos,zPos);
}
}
}
}
return null;
}
public int getRoadSpacer()
{
return 1;
}
}

View file

@ -0,0 +1,181 @@
#Block Localization
tile.bloodAltar.name=Altare del Sangue
tile.bloodRune.blank.name=Runa del Sangue
tile.bloodRune.fill.name=Runa di Capacità Aumentata
tile.bloodRune.empty.name=Runa di Dislocazione
tile.bloodRune.test.name=Runa del Globo
tile.speedRune.name=Runa di Velocità
tile.efficiencyRune.name=Runa di Efficienza
tile.runeOfSacrifice.name=Runa del Sacrificio
tile.runeOfSelfSacrifice.name=Runa di Auto-Sacrificio
tile.ritualStone.name=Pietra del Rituale
tile.blockMasterStone.name=Pietra Maestra del Rituale
tile.bloodSocket.name=Cavità Piena
tile.imperfectRitualStone.name=Pietra del Rituale Imperfetta
tile.armourForge.name=Forgia delle Armature dell'Anima
tile.emptySocket.name=Cavità Vuota
tile.bloodStoneBrick.name=Mattone di Pietra del Sangue
tile.largeBloodStoneBrick.name=Gran Mattone di Pietra del Sangue
tile.blockWritingTable.name=Set da Alchimista
tile.blockHomHeart.name=Tavolo della Magia
tile.bloodPedestal.name=Piedistallo Arcano
tile.bloodPlinth.name=Basamento Arcano
tile.bloodTeleposer.name=Teleposer
tile.blockConduit.name=Condotto di Magia
tile.blockSpellParadigm.projectile.name=Generatore di Particelle
tile.blockSpellParadigm.self.name=Auto-Miglioratore
tile.blockSpellParadigm.melee.name=Aggregatore di Mischia
tile.blockSpellEnhancement.power1.name=Potenziatore Instabile di Magia
tile.blockSpellEnhancement.power2.name=Potenziatore Standard di Magia
tile.blockSpellEnhancement.power3.name=Potenziatore Rinforzato di Magia
tile.blockSpellEnhancement.power4.name=Potenziatore Invaso di Magia
tile.blockSpellEnhancement.power5.name=Potenziatore Demoniaco di Magia
tile.blockSpellEnhancement.cost1.name=Smorzatore Instabile di Magia
tile.blockSpellEnhancement.cost2.name=Smorzatore Standard di Magia
tile.blockSpellEnhancement.cost3.name=Smorzatore Rinforzato di Magia
tile.blockSpellEnhancement.cost4.name=Smorzatore Invaso di Magia
tile.blockSpellEnhancement.cost5.name=Smorzatore Demoniaco di Magia
tile.blockSpellEnhancement.potency1.name=Miglioratore Instabile di Magia
tile.blockSpellEnhancement.potency2.name=Miglioratore Standard di Magia
tile.blockSpellEnhancement.potency3.name=Miglioratore Rinforzato di Magia
tile.blockSpellEnhancement.potency4.name=Miglioratore Invaso di Magia
tile.blockSpellEnhancement.potency5.name=Miglioratore Demoniaco di Magia
tile.blockSpellModifier.default.name=Modificatore di Magia
tile.blockSpellModifier.offensive.name=Modificatore di Magia Offensiva
tile.blockSpellModifier.defensive.name=Modificatore di Magia Difensiva
tile.blockSpellModifier.environmental.name=Modificatore di Magia Ambientale
tile.blockSpellEffect.fire.name=Crogiolo del Fuoco
tile.blockSpellEffect.ice.name=Creatore di Ghiaccio
tile.blockSpellEffect.wind.name=Generatore del Vento
tile.blockSpellEffect.earth.name=Formatore della Terra
#Item Localization
item.weakBloodOrb.name=Globo di Sangue Debole
item.apprenticeBloodOrb.name=Globo di Sangue dell'Apprendista
item.magicianBloodOrb.name=Globo di Sangue del Mago
item.masterBloodOrb.name=Globo di Sangue del Maestro
item.archmageBloodOrb.name=Globo di Sangue dell'Arcimago
item.energyBlast.name=Blaster Energetico
item.energySword.name=Lama Legata
item.lavaCrystal.name=Cristallo Lavico
item.waterSigil.name=Sigillo dell'Acqua
item.lavaSigil.name=Sigillo di Lava
item.voidSigil.name=Sigillo del Vuoto
item.blankSlate.name=Ardesia Bianca
item.reinforcedSlate.name=Ardesia Rinforzata
item.sacrificialDagger.name=Pugnale Sacrificale
item.daggerOfSacrifice.name=Daga Sacrificale
item.airSigil.name=Sigillo dell'Aria
item.sigilOfTheFastMiner.name=Sigillo del Rapido Minatore
item.sigilOfElementalAffinity.name=Sigillo di Affinità Elementale
item.sigilOfHaste.name=Sigillo di Rapidità
item.sigilOfHolding.name=Sigillo della Tenacia Egoista
item.divinationSigil.name=Sigillo di Divinatione
item.waterScribeTool.name=Utensile d'Iscrizione Elementale: Acqua
item.fireScribeTool.name=Utensile d'Iscrizione Elementale: Fuoco
item.earthScribeTool.name=Utensile d'Iscrizione Elementale: Terra
item.airScribeTool.name=Utensile d'Iscrizione Elementale: Aria
item.duskScribeTool.name=Utensile d'Iscrizione Elementale: Crepuscolo
item.activationCrystalWeak.name=Cristallo d'Attivazione Debole
item.activationCrystalAwakened.name=Cristallo d'Attivazione Risvegliato
item.boundPickaxe.name=Piccone Vincolato
item.boundAxe.name=Ascia Vincolata
item.boundShovel.name=Vanga Vincolata
item.boundHelmet.name=Elmo Vincolato
item.boundPlate.name=Piastra Vincolata
item.boundLeggings.name=Gambali Vincolati
item.boundBoots.name=Stivali Vincolati
item.weakBloodShard.name=Scheggia di Sangue Debole
item.growthSigil.name=Sigillo del Verde Bosco
item.blankSpell.name=Cristallo non Vincolato
item.alchemyFlask.name=Boccetta per Pozione
item.standardBindingAgent.name=Agente Vincolante Standard
item.mundanePowerCatalyst.name=Catalizzatore Comune di Potere
item.averagePowerCatalyst.name=Catalizzatore Medio di Potere
item.greaterPowerCatalyst.name=Catalizzatore Maggiore di Potere
item.mundaneLengtheningCatalyst.name=Catalizzatore Procastinante Comune
item.averageLengtheningCatalyst.name=Catalizzatore Procastinante Medio
item.greaterLengtheningCatalyst.name=Catalizzatore Procastinante Maggiore
item.incendium.name=Incendium
item.magicales.name=Magicales
item.sanctus.name=Sanctus
item.aether.name=Etere
item.simpleCatalyst.name=Catalizzatore Semplice
item.crepitous.name=Crepitous
item.crystallos.name=Crystallos
item.terrae.name=Terrae
item.aquasalus.name=Aquasalus
item.tennebrae.name=Tenebrae
item.demonBloodShard.name=Scheggia di Sangue di Demone
item.sigilOfWind.name=Sigillo del Vortice
item.telepositionFocus.name=Focus di Teleposizione
item.enhancedTelepositionFocus.name=Focus Migliorato di Teleposizione
item.reinforcedTelepositionFocus.name=Focus Rinforzato di Teleposizione
item.demonicTelepositionFocus.name=Focus Demoniaco di Teleposizione
item.imbuedSlate.name=Piastra Invasa
item.demonicSlate.name=Piastra Demoniaca
item.sigilOfTheBridge.name=Sigillo del POnte Spettrale
item.armourInhibitor.name=Inibitore di Armatura
item.cheatyItem.name=Globo di Prova
item.weakFillingAgent.name=Agente Riempiente Debole
item.standardFillingAgent.name=Agente Riempiente Standard
item.enhancedFillingAgent.name=Agente Riempiente Potenziato
item.weakBindingAgent.name=Agente Vincolante Debole
item.ritualDiviner.name=Divinatore del Rituale
item.sigilOfMagnetism.name=Sigillo del Magnetismo
item.itemDiabloKey.name=Chiave del Vincolo
item.energyBazooka.name=Cannone Energetico
item.bloodLightSigil.name=Sigillo della Torcia di Sangue
item.itemComplexSpellCrystal.name=Cristallo Magico Complesso
item.itemSigilOfSupression.name=Sigillo di Soppressione
item.itemSigilOfEnderSeverance.name=Sigillo di Disgiunzione Ender
item.bucketLive.name=Secchio di Vita
item.bloodMagicBaseItem.QuartzRod.name=Verga di Quarzo
item.bloodMagicBaseItem.EmptyCore.name=Nucleo Vuoto
item.bloodMagicBaseItem.MagicalesCable.name=Connessione Magicales
item.bloodMagicBaseItem.WoodBrace.name=Pilastro di Legno
item.bloodMagicBaseItem.StoneBrace.name=Pilastro di Pietra
item.bloodMagicBaseItem.ProjectileCore.name=Nucleo Proiettile
item.bloodMagicBaseItem.SelfCore.name=Auto-Nucleo
item.bloodMagicBaseItem.MeleeCore.name=Nucleo di Mischia
item.bloodMagicBaseItem.ParadigmBackPlate.name=Piastra Modello
item.bloodMagicBaseItem.OutputCable.name=Connessione in Uscita di Magia
item.bloodMagicBaseItem.InputCable.name=Connessione in Entrata di Magia
item.bloodMagicBaseItem.FlameCore.name=Nucleo Infuocato
item.bloodMagicBaseItem.IcyCore.name=Nucleo Ghiacciato
item.bloodMagicBaseItem.GustCore.name=Nucleo Ventoso
item.bloodMagicBaseItem.EarthenCore.name=Nucleo Terroso
item.bloodMagicBaseItem.CrackedRunicPlate.name=Piastra Runica Incrinata
item.bloodMagicBaseItem.RunicPlate.name=Piastra Runica
item.bloodMagicBaseItem.ScribedRunicPlate.name=Piastra Runica Invasa
item.bloodMagicBaseItem.DefaultCore.name=Nucleo Disarmonico
item.bloodMagicBaseItem.OffensiveCore.name=Nucleo Offensivo
item.bloodMagicBaseItem.DefensiveCore.name=Nucleo Difensivo
item.bloodMagicBaseItem.EnvironmentalCore.name=Nucleo Ambientale
item.bloodMagicBaseItem.PowerCore.name=Nucleo di Forza
item.bloodMagicBaseItem.CostCore.name=Nucleo di Riduzione
item.bloodMagicBaseItem.PotencyCore.name=Nucleo di Potenza
item.bloodMagicBaseItem.ObsidianBrace.name=Pilastro di Ossidiana
item.bloodMagicAlchemyItem.Offensa.name=Offensa
item.bloodMagicAlchemyItem.Praesidium.name=Praesidium
item.bloodMagicAlchemyItem.OrbisTerrae.name=Orbis Terrae
item.bloodMagicAlchemyItem.StrengthenedCatalyst.name=Catalizzatore Rafforzato
item.bloodMagicAlchemyItem.ConcentratedCatalyst.name=Catalizzatore Concentrato
item.bloodMagicAlchemyItem.FracturedBone.name=Osso Fratturato
item.bloodMagicAlchemyItem.Virtus.name=Virtus
item.bloodMagicAlchemyItem.Reductus.name=Reductus
item.bloodMagicAlchemyItem.Potentia.name=Potentia
item.sanguineHelmet.name=Elmo Sanguigno
item.itemSeerSigil.name=Sigillo della Veduta
item.itemFluidSigil.name=
#Creative Tab
itemGroup.tabBloodMagic=Magia del Sangue
#Extra Strings
bm.string.consume=Utilizzo
bm.string.drain=Drenaggio
bm.string.tier=Livello
bm.string.crafting.orb.shaped=Creazione di un Glodo Formato
bm.string.crafting.orb.shapeless=Creazione di un Globo Informe