Creation of 1.16.3 branch

Initial publishing of the 1.16.3 branch of the mod. A lot of systems are missing (such as Rituals and Living Armour), but enough is present for a decent Alpha release.
This commit is contained in:
WayofTime 2020-10-24 08:59:04 -04:00
parent 0e02b983f1
commit d617911d7a
1662 changed files with 18791 additions and 85075 deletions

View file

@ -1,175 +1,152 @@
package WayofTime.bloodmagic.tile;
package wayoftime.bloodmagic.tile;
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffect;
import WayofTime.bloodmagic.alchemyArray.AlchemyArrayEffectCraftingNew;
import WayofTime.bloodmagic.api.impl.BloodMagicAPI;
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyArray;
import WayofTime.bloodmagic.core.registry.AlchemyArrayRecipeRegistry;
import WayofTime.bloodmagic.iface.IAlchemyArray;
import WayofTime.bloodmagic.util.Constants;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.registries.ObjectHolder;
import wayoftime.bloodmagic.common.alchemyarray.AlchemyArrayEffect;
import wayoftime.bloodmagic.core.registry.AlchemyArrayRegistry;
import wayoftime.bloodmagic.util.Constants;
public class TileAlchemyArray extends TileInventory implements ITickable, IAlchemyArray {
public boolean isActive = false;
public int activeCounter = 0;
public Direction rotation = Direction.HORIZONTALS[0];
public int rotateCooldown = 0;
public class TileAlchemyArray extends TileInventory implements ITickableTileEntity
{
@ObjectHolder("bloodmagic:alchemyarray")
public static TileEntityType<TileAlchemyArray> TYPE;
private String key = "empty";
public AlchemyArrayEffect arrayEffect;
private boolean doDropIngredients = true;
public boolean isActive = false;
public int activeCounter = 0;
public Direction rotation = Direction.byHorizontalIndex(0);
public int rotateCooldown = 0;
public TileAlchemyArray() {
super(2, "alchemyArray");
}
private String key = "";
public AlchemyArrayEffect arrayEffect;
private boolean doDropIngredients = true;
public void onEntityCollidedWithBlock(BlockState state, Entity entity) {
if (arrayEffect != null) {
arrayEffect.onEntityCollidedWithBlock(this, getWorld(), pos, state, entity);
}
}
public TileAlchemyArray(TileEntityType<?> type)
{
super(type, 2, "alchemyarray");
// this.bloodAltar = new BloodAltar(this);
}
@Override
public void deserialize(CompoundNBT tagCompound) {
super.deserialize(tagCompound);
this.isActive = tagCompound.getBoolean("isActive");
this.activeCounter = tagCompound.getInt("activeCounter");
this.key = tagCompound.getString("key");
if (!tagCompound.hasKey("doDropIngredients")) //Check if the array is old
{
this.doDropIngredients = true;
} else {
this.doDropIngredients = tagCompound.getBoolean("doDropIngredients");
}
this.rotation = Direction.HORIZONTALS[tagCompound.getInt(Constants.NBT.DIRECTION)];
public TileAlchemyArray()
{
this(TYPE);
}
CompoundNBT arrayTag = tagCompound.getCompoundTag("arrayTag");
arrayEffect = AlchemyArrayRecipeRegistry.getAlchemyArrayEffect(key);
if (arrayEffect != null) {
arrayEffect.readFromNBT(arrayTag);
}
}
@Override
public void deserialize(CompoundNBT tagCompound)
{
super.deserialize(tagCompound);
this.isActive = tagCompound.getBoolean("isActive");
this.activeCounter = tagCompound.getInt("activeCounter");
this.key = tagCompound.getString("stringKey");
if (!tagCompound.contains("doDropIngredients")) // Check if the array is old
{
this.doDropIngredients = true;
} else
{
this.doDropIngredients = tagCompound.getBoolean("doDropIngredients");
}
this.rotation = Direction.byHorizontalIndex(tagCompound.getInt(Constants.NBT.DIRECTION));
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
super.serialize(tagCompound);
tagCompound.putBoolean("isActive", isActive);
tagCompound.putInt("activeCounter", activeCounter);
tagCompound.putString("key", "".equals(key) ? "empty" : key);
tagCompound.putBoolean("doDropIngredients", doDropIngredients);
tagCompound.putInt(Constants.NBT.DIRECTION, rotation.getHorizontalIndex());
CompoundNBT arrayTag = tagCompound.getCompound("arrayTag");
// arrayEffect = AlchemyArrayRegistry.getEffect(world, this.getStackInSlot(0), this.getStackInSlot(1));
if (arrayEffect != null)
{
arrayEffect.readFromNBT(arrayTag);
}
}
CompoundNBT arrayTag = new CompoundNBT();
if (arrayEffect != null) {
arrayEffect.writeToNBT(arrayTag);
}
tagCompound.putTag("arrayTag", arrayTag);
@Override
public CompoundNBT serialize(CompoundNBT tagCompound)
{
super.serialize(tagCompound);
tagCompound.putBoolean("isActive", isActive);
tagCompound.putInt("activeCounter", activeCounter);
tagCompound.putString("stringKey", "".equals(key) ? "empty" : key.toString());
tagCompound.putBoolean("doDropIngredients", doDropIngredients);
tagCompound.putInt(Constants.NBT.DIRECTION, rotation.getHorizontalIndex());
return tagCompound;
}
CompoundNBT arrayTag = new CompoundNBT();
if (arrayEffect != null)
{
arrayEffect.writeToNBT(arrayTag);
}
tagCompound.put("arrayTag", arrayTag);
@Override
public int getInventoryStackLimit() {
return 1;
}
return tagCompound;
}
//Use this to prevent the Array from dropping items - useful for arrays that need to "consume" ingredients well before the effect.
public void setItemDrop(boolean dropItems) {
this.doDropIngredients = dropItems;
}
@Override
public void tick()
{
// System.out.println("Active counter: " + this.activeCounter);
if (isActive && attemptCraft())
{
activeCounter++;
} else
{
isActive = false;
doDropIngredients = true;
activeCounter = 0;
arrayEffect = null;
key = "empty";
}
if (rotateCooldown > 0)
rotateCooldown--;
}
@Override
public void update() {
if (isActive && attemptCraft()) {
activeCounter++;
} else {
isActive = false;
doDropIngredients = true;
activeCounter = 0;
arrayEffect = null;
key = "empty";
}
if (rotateCooldown > 0)
rotateCooldown--;
}
public boolean attemptCraft()
{
if (arrayEffect != null)
{
isActive = true;
/**
* This occurs when the block is destroyed.
*/
@Override
public void dropItems() {
if (arrayEffect == null || doDropIngredients) {
super.dropItems();
}
}
} else
{
AlchemyArrayEffect effect = AlchemyArrayRegistry.getEffect(world, this.getStackInSlot(0), this.getStackInSlot(1));
if (effect == null)
{
// key = effect.i
return false;
} else
{
arrayEffect = effect;
}
}
public boolean attemptCraft() {
AlchemyArrayEffect effect = AlchemyArrayRecipeRegistry.getAlchemyArrayEffect(this.getStackInSlot(0), this.getStackInSlot(1));
if (effect != null) {
if (arrayEffect == null) {
arrayEffect = effect;
key = effect.getKey();
} else {
String effectKey = effect.getKey();
if (effectKey.equals(key)) {
//Good! Moving on.
} else {
//Something has changed, therefore we have to move our stuffs.
//TODO: Add an AlchemyArrayEffect.onBreak(); ?
arrayEffect = effect;
key = effect.getKey();
}
}
} else {
RecipeAlchemyArray recipe = BloodMagicAPI.INSTANCE.getRecipeRegistrar().getAlchemyArray(getStackInSlot(0), getStackInSlot(1));
if (recipe == null)
return false;
if (arrayEffect != null)
{
isActive = true;
if (arrayEffect.update(this, this.activeCounter))
{
this.decrStackSize(0, 1);
this.decrStackSize(1, 1);
this.getWorld().setBlockState(getPos(), Blocks.AIR.getDefaultState());
}
AlchemyArrayEffect newEffect = new AlchemyArrayEffectCraftingNew(recipe);
if (arrayEffect == null) {
arrayEffect = newEffect;
key = newEffect.key;
} else if (!newEffect.key.equals(key)) {
arrayEffect = newEffect;
key = newEffect.key;
}
}
return true;
}
return false;
}
if (arrayEffect != null) {
isActive = true;
// @Override
public Direction getRotation()
{
return rotation;
}
if (arrayEffect.update(this, this.activeCounter)) {
this.decrStackSize(0, 1);
this.decrStackSize(1, 1);
this.getWorld().setBlockToAir(getPos());
}
public void setRotation(Direction rotation)
{
this.rotation = rotation;
}
return true;
}
return false;
}
@Override
public Direction getRotation() {
return rotation;
}
public void setRotation(Direction rotation) {
this.rotation = rotation;
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getRenderBoundingBox() {
return Block.FULL_BLOCK_AABB.offset(getPos());
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
return slot == 0 || slot == 1;
}
}

View file

@ -1,432 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.api.event.BloodMagicCraftedEvent;
import WayofTime.bloodmagic.api.impl.BloodMagicAPI;
import WayofTime.bloodmagic.api.impl.recipe.RecipeAlchemyTable;
import WayofTime.bloodmagic.core.data.*;
import WayofTime.bloodmagic.core.registry.AlchemyTableRecipeRegistry;
import WayofTime.bloodmagic.iface.IBindable;
import WayofTime.bloodmagic.iface.ICustomAlchemyConsumable;
import WayofTime.bloodmagic.orb.BloodOrb;
import WayofTime.bloodmagic.orb.IBloodOrb;
import WayofTime.bloodmagic.recipe.alchemyTable.AlchemyTableRecipe;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.util.helper.NetworkHelper;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import org.apache.commons.lang3.ArrayUtils;
import java.util.ArrayList;
import java.util.List;
public class TileAlchemyTable extends TileInventory implements ISidedInventory, ITickable {
public static final int orbSlot = 6;
public static final int toolSlot = 7;
public static final int outputSlot = 8;
public Direction direction = Direction.NORTH;
public boolean isSlave = false;
public int burnTime = 0;
public int ticksRequired = 1;
public BlockPos connectedPos = BlockPos.ORIGIN;
public boolean[] blockedSlots = new boolean[]{false, false, false, false, false, false};
public TileAlchemyTable() {
super(9, "alchemyTable");
}
public void setInitialTableParameters(Direction direction, boolean isSlave, BlockPos connectedPos) {
this.isSlave = isSlave;
this.connectedPos = connectedPos;
if (!isSlave) {
this.direction = direction;
}
}
public boolean isInvisible() {
return isSlave();
}
public boolean isInputSlotAccessible(int slot) {
return !(slot < 6 && slot >= 0) || !blockedSlots[slot];
}
public void toggleInputSlotAccessible(int slot) {
if (slot < 6 && slot >= 0)
blockedSlots[slot] = !blockedSlots[slot];
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
isSlave = tag.getBoolean("isSlave");
direction = Direction.byIndex(tag.getInt(Constants.NBT.DIRECTION));
connectedPos = new BlockPos(tag.getInt(Constants.NBT.X_COORD), tag.getInt(Constants.NBT.Y_COORD), tag.getInt(Constants.NBT.Z_COORD));
burnTime = tag.getInt("burnTime");
ticksRequired = tag.getInt("ticksRequired");
byte[] array = tag.getByteArray("blockedSlots");
for (int i = 0; i < array.length; i++)
blockedSlots[i] = array[i] != 0;
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putBoolean("isSlave", isSlave);
tag.putInt(Constants.NBT.DIRECTION, direction.getIndex());
tag.putInt(Constants.NBT.X_COORD, connectedPos.getX());
tag.putInt(Constants.NBT.Y_COORD, connectedPos.getY());
tag.putInt(Constants.NBT.Z_COORD, connectedPos.getZ());
tag.putInt("burnTime", burnTime);
tag.putInt("ticksRequired", ticksRequired);
byte[] blockedSlotArray = new byte[blockedSlots.length];
for (int i = 0; i < blockedSlots.length; i++)
blockedSlotArray[i] = (byte) (blockedSlots[i] ? 1 : 0);
tag.putByteArray("blockedSlots", blockedSlotArray);
return tag;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, Direction facing) {
if (facing != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if (this.isSlave()) {
TileEntity tile = getWorld().getTileEntity(connectedPos);
if (tile instanceof TileAlchemyTable && !((TileAlchemyTable) tile).isSlave) {
return (T) tile.getCapability(capability, facing);
}
} else {
return super.getCapability(capability, facing);
}
}
return super.getCapability(capability, facing);
}
@Override
public int[] getSlotsForFace(Direction side) {
switch (side) {
case DOWN:
return new int[]{outputSlot};
case UP:
return new int[]{orbSlot, toolSlot};
default:
return new int[]{0, 1, 2, 3, 4, 5};
}
}
@Override
public boolean canInsertItem(int index, ItemStack stack, Direction direction) {
switch (direction) {
case DOWN:
return index != outputSlot && index != orbSlot && index != toolSlot;
case UP:
if (index == orbSlot && !stack.isEmpty() && stack.getItem() instanceof IBloodOrb) {
return true;
} else if (index == toolSlot) {
return false; //TODO:
} else {
return true;
}
default:
if (this.isSlave) {
TileEntity tile = getWorld().getTileEntity(connectedPos);
if (tile instanceof TileAlchemyTable && !((TileAlchemyTable) tile).isSlave) {
return ((TileAlchemyTable) tile).canInsertItem(index, stack, direction);
}
}
return getAccessibleInputSlots(direction).contains(index);
}
}
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction) {
switch (direction) {
case DOWN:
return index == outputSlot;
case UP:
if (index == orbSlot && !stack.isEmpty() && stack.getItem() instanceof IBloodOrb) {
return true;
} else if (index == toolSlot) {
return true; //TODO:
} else {
return true;
}
default:
if (this.isSlave) {
TileEntity tile = getWorld().getTileEntity(connectedPos);
if (tile instanceof TileAlchemyTable && !((TileAlchemyTable) tile).isSlave) {
return ((TileAlchemyTable) tile).canExtractItem(index, stack, direction);
}
}
return getAccessibleInputSlots(direction).contains(index);
}
}
public List<Integer> getAccessibleInputSlots(Direction direction) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 6; i++) {
if (isInputSlotAccessible(i)) {
list.add(i);
}
}
return list;
}
@Override
public void update() {
if (isSlave()) {
return;
}
List<ItemStack> inputList = new ArrayList<>();
for (int i = 0; i < 6; i++) {
if (!getStackInSlot(i).isEmpty()) {
inputList.add(getStackInSlot(i));
}
}
int tier = getTierOfOrb();
// special recipes like dying
AlchemyTableRecipe recipe = AlchemyTableRecipeRegistry.getMatchingRecipe(inputList, getWorld(), getPos());
if (recipe != null && (burnTime > 0 || (!getWorld().isRemote && tier >= recipe.getTierRequired() && this.getContainedLp() >= recipe.getLpDrained()))) {
if (burnTime == 1)
notifyUpdate();
if (canCraft(recipe.getRecipeOutput(inputList))) {
ticksRequired = recipe.getTicksRequired();
burnTime++;
if (burnTime == ticksRequired) {
if (!getWorld().isRemote) {
int requiredLp = recipe.getLpDrained();
if (requiredLp > 0) {
if (!getWorld().isRemote) {
consumeLp(requiredLp);
}
}
if (!getWorld().isRemote) {
craftItem(inputList, recipe);
}
}
burnTime = 0;
BlockState state = getWorld().getBlockState(pos);
getWorld().notifyBlockUpdate(getPos(), state, state, 3);
} else if (burnTime > ticksRequired + 10) {
burnTime = 0;
}
} else {
burnTime = 0;
}
} else { // Simple recipes
RecipeAlchemyTable recipeAlchemyTable = BloodMagicAPI.INSTANCE.getRecipeRegistrar().getAlchemyTable(inputList);
if (recipeAlchemyTable != null && (burnTime > 0 || (!getWorld().isRemote && tier >= recipeAlchemyTable.getMinimumTier() && getContainedLp() >= recipeAlchemyTable.getSyphon()))) {
if (burnTime == 1)
notifyUpdate();
if (canCraft(recipeAlchemyTable.getOutput())) {
ticksRequired = recipeAlchemyTable.getTicks();
burnTime++;
if (burnTime >= ticksRequired) {
if (!getWorld().isRemote) {
if (recipeAlchemyTable.getSyphon() > 0) {
if (consumeLp(recipeAlchemyTable.getSyphon()) < recipeAlchemyTable.getSyphon()) {
//There was not enough LP to craft or there was no orb
burnTime = 0;
notifyUpdate();
return;
}
}
ItemStack[] inputs = new ItemStack[0];
for (ItemStack stack : inputList)
ArrayUtils.add(inputs, stack.copy());
BloodMagicCraftedEvent.AlchemyTable event = new BloodMagicCraftedEvent.AlchemyTable(recipeAlchemyTable.getOutput().copy(), inputs);
MinecraftForge.EVENT_BUS.post(event);
ItemStack outputSlotStack = getStackInSlot(outputSlot);
if (outputSlotStack.isEmpty())
setInventorySlotContents(outputSlot, event.getOutput());
else
outputSlotStack.grow(event.getOutput().getCount());
for (int i = 0; i < 6; i++) {
ItemStack currentStack = getStackInSlot(i);
if (currentStack.getItem().hasContainerItem(currentStack))
setInventorySlotContents(i, currentStack.getItem().getContainerItem(currentStack));
else if (currentStack.getItem() instanceof ICustomAlchemyConsumable)
setInventorySlotContents(i, ((ICustomAlchemyConsumable) currentStack.getItem()).drainUseOnAlchemyCraft(currentStack));
else
currentStack.shrink(1);
}
burnTime = 0;
notifyUpdate();
}
}
}
} else {
burnTime = 0;
}
}
}
public double getProgressForGui() {
return ((double) burnTime) / ticksRequired;
}
private boolean canCraft(ItemStack output) {
ItemStack currentOutputStack = getStackInSlot(outputSlot);
if (output.isEmpty())
return false;
if (currentOutputStack.isEmpty())
return true;
if (!ItemHandlerHelper.canItemStacksStack(output, currentOutputStack))
return false;
int result = currentOutputStack.getCount() + output.getCount();
return result <= getInventoryStackLimit() && result <= currentOutputStack.getMaxStackSize();
}
public int getTierOfOrb() {
ItemStack orbStack = getStackInSlot(orbSlot);
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
BloodOrb orb = ((IBloodOrb) orbStack.getItem()).getOrb(orbStack);
return orb == null ? 0 : orb.getTier();
}
}
return 0;
}
public int getContainedLp() {
ItemStack orbStack = getStackInSlot(orbSlot);
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
Binding binding = ((IBindable) orbStack.getItem()).getBinding(orbStack);
if (binding == null) {
return 0;
}
SoulNetwork network = NetworkHelper.getSoulNetwork(binding);
return network.getCurrentEssence();
}
}
return 0;
}
public void craftItem(List<ItemStack> inputList, AlchemyTableRecipe recipe) {
ItemStack outputStack = recipe.getRecipeOutput(inputList);
if (this.canCraft(outputStack)) {
ItemStack currentOutputStack = getStackInSlot(outputSlot);
ItemStack[] inputs = new ItemStack[0];
for (ItemStack stack : inputList)
ArrayUtils.add(inputs, stack.copy());
BloodMagicCraftedEvent.AlchemyTable event = new BloodMagicCraftedEvent.AlchemyTable(outputStack.copy(), inputs);
MinecraftForge.EVENT_BUS.post(event);
outputStack = event.getOutput();
if (currentOutputStack.isEmpty()) {
setInventorySlotContents(outputSlot, outputStack);
} else if (ItemHandlerHelper.canItemStacksStack(outputStack, currentOutputStack)) {
currentOutputStack.grow(outputStack.getCount());
}
consumeInventory(recipe);
}
}
public int consumeLp(int requested) {
ItemStack orbStack = getStackInSlot(orbSlot);
if (!orbStack.isEmpty()) {
if (orbStack.getItem() instanceof IBloodOrb) {
if (NetworkHelper.syphonFromContainer(orbStack, SoulTicket.item(orbStack, world, pos, requested))) {
return requested;
}
}
}
return 0;
}
public void consumeInventory(AlchemyTableRecipe recipe) {
ItemStack[] input = new ItemStack[6];
for (int i = 0; i < 6; i++) {
input[i] = getStackInSlot(i);
}
ItemStack[] result = recipe.getRemainingItems(input);
for (int i = 0; i < 6; i++) {
setInventorySlotContents(i, result[i]);
}
}
public Direction getDirection() {
return direction;
}
public boolean isSlave() {
return isSlave;
}
public int getBurnTime() {
return burnTime;
}
public int getTicksRequired() {
return ticksRequired;
}
public BlockPos getConnectedPos() {
return connectedPos;
}
public boolean[] getBlockedSlots() {
return blockedSlots;
}
public static int getOrbSlot() {
return orbSlot;
}
public static int getToolSlot() {
return toolSlot;
}
public static int getOutputSlot() {
return outputSlot;
}
}

View file

@ -1,190 +1,227 @@
package WayofTime.bloodmagic.tile;
package wayoftime.bloodmagic.tile;
import WayofTime.bloodmagic.altar.BloodAltar;
import WayofTime.bloodmagic.altar.AltarTier;
import WayofTime.bloodmagic.altar.IBloodAltar;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.registries.ObjectHolder;
import wayoftime.bloodmagic.altar.AltarTier;
import wayoftime.bloodmagic.altar.BloodAltar;
import wayoftime.bloodmagic.altar.IBloodAltar;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class TileAltar extends TileInventory implements IBloodAltar, ITickableTileEntity
{
@ObjectHolder("bloodmagic:altar")
public static TileEntityType<TileAltar> TYPE;
private BloodAltar bloodAltar;
public class TileAltar extends TileInventory implements IBloodAltar, ITickable {
private BloodAltar bloodAltar;
public TileAltar(TileEntityType<?> type)
{
super(type, 1, "altar");
this.bloodAltar = new BloodAltar(this);
}
public TileAltar() {
super(1, "altar");
this.bloodAltar = new BloodAltar(this);
}
public TileAltar()
{
this(TYPE);
}
@Override
public void deserialize(CompoundNBT tagCompound) {
super.deserialize(tagCompound);
@Override
public void deserialize(CompoundNBT tagCompound)
{
super.deserialize(tagCompound);
CompoundNBT altarTag = tagCompound.getCompoundTag("bloodAltar");
CompoundNBT altarTag = tagCompound.getCompound("bloodAltar");
this.bloodAltar.readFromNBT(altarTag);
}
this.bloodAltar.readFromNBT(altarTag);
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
super.serialize(tagCompound);
@Override
public CompoundNBT serialize(CompoundNBT tagCompound)
{
super.serialize(tagCompound);
CompoundNBT altarTag = new CompoundNBT();
this.bloodAltar.writeToNBT(altarTag);
CompoundNBT altarTag = new CompoundNBT();
this.bloodAltar.writeToNBT(altarTag);
tagCompound.putTag("bloodAltar", altarTag);
return tagCompound;
}
tagCompound.put("bloodAltar", altarTag);
return tagCompound;
}
@Override
public void update() {
bloodAltar.update();
}
@Override
public void tick()
{
bloodAltar.update();
}
@Override
public void sacrificialDaggerCall(int amount, boolean isSacrifice) {
bloodAltar.sacrificialDaggerCall(amount, isSacrifice);
}
@Override
public void sacrificialDaggerCall(int amount, boolean isSacrifice)
{
bloodAltar.sacrificialDaggerCall(amount, isSacrifice);
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack) {
return slot == 0;
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack)
{
return slot == 0;
}
@Override
public int getCapacity() {
return bloodAltar.getCapacity();
}
@Override
public int getCapacity()
{
return bloodAltar.getCapacity();
}
@Override
public int getCurrentBlood() {
return bloodAltar.getCurrentBlood();
}
@Override
public int getCurrentBlood()
{
return bloodAltar.getCurrentBlood();
}
@Override
public AltarTier getTier() {
return bloodAltar.getTier();
}
@Override
public AltarTier getTier()
{
return bloodAltar.getTier();
}
@Override
public int getProgress() {
return bloodAltar.getProgress();
}
@Override
public int getProgress()
{
return bloodAltar.getProgress();
}
@Override
public float getSacrificeMultiplier() {
return bloodAltar.getSacrificeMultiplier();
}
@Override
public float getSacrificeMultiplier()
{
return bloodAltar.getSacrificeMultiplier();
}
@Override
public float getSelfSacrificeMultiplier() {
return bloodAltar.getSelfSacrificeMultiplier();
}
@Override
public float getSelfSacrificeMultiplier()
{
return bloodAltar.getSelfSacrificeMultiplier();
}
@Override
public float getOrbMultiplier() {
return bloodAltar.getOrbMultiplier();
}
@Override
public float getOrbMultiplier()
{
return bloodAltar.getOrbMultiplier();
}
@Override
public float getDislocationMultiplier() {
return bloodAltar.getDislocationMultiplier();
}
@Override
public float getDislocationMultiplier()
{
return bloodAltar.getDislocationMultiplier();
}
@Override
public float getConsumptionMultiplier() {
return bloodAltar.getConsumptionMultiplier();
}
@Override
public float getConsumptionMultiplier()
{
return bloodAltar.getConsumptionMultiplier();
}
@Override
public float getConsumptionRate() {
return bloodAltar.getConsumptionRate();
}
@Override
public float getConsumptionRate()
{
return bloodAltar.getConsumptionRate();
}
@Override
public int getLiquidRequired() {
return bloodAltar.getLiquidRequired();
}
@Override
public int getLiquidRequired()
{
return bloodAltar.getLiquidRequired();
}
@Override
public int getBufferCapacity() {
return bloodAltar.getBufferCapacity();
}
@Override
public int getBufferCapacity()
{
return bloodAltar.getBufferCapacity();
}
@Override
public void startCycle() {
bloodAltar.startCycle();
}
@Override
public void startCycle()
{
bloodAltar.startCycle();
}
@Override
public void checkTier() {
bloodAltar.checkTier();
}
@Override
public void checkTier()
{
bloodAltar.checkTier();
}
@Override
public void requestPauseAfterCrafting(int cooldown) {
bloodAltar.requestPauseAfterCrafting(cooldown);
}
@Override
public void requestPauseAfterCrafting(int cooldown)
{
bloodAltar.requestPauseAfterCrafting(cooldown);
}
@Override
public boolean isActive() {
return bloodAltar.isActive();
}
@Override
public boolean isActive()
{
return bloodAltar.isActive();
}
@Override
public int fillMainTank(int amount) {
return bloodAltar.fillMainTank(amount);
}
@Override
public int fillMainTank(int amount)
{
return bloodAltar.fillMainTank(amount);
}
@Override
public void setActive() {
bloodAltar.setActive();
}
@Override
public void setActive()
{
bloodAltar.setActive();
}
@Override
public int getChargingRate() {
return bloodAltar.getChargingRate();
}
@Override
public int getChargingRate()
{
return bloodAltar.getChargingRate();
}
@Override
public int getTotalCharge() {
return bloodAltar.getTotalCharge();
}
@Override
public int getTotalCharge()
{
return bloodAltar.getTotalCharge();
}
@Override
public int getChargingFrequency() {
return bloodAltar.getChargingFrequency();
}
@Override
public int getChargingFrequency()
{
return bloodAltar.getChargingFrequency();
}
public AltarTier getCurrentTierDisplayed() {
return bloodAltar.getCurrentTierDisplayed();
}
public AltarTier getCurrentTierDisplayed()
{
return bloodAltar.getCurrentTierDisplayed();
}
public boolean setCurrentTierDisplayed(AltarTier altarTier) {
return bloodAltar.setCurrentTierDisplayed(altarTier);
}
public boolean setCurrentTierDisplayed(AltarTier altarTier)
{
return bloodAltar.setCurrentTierDisplayed(altarTier);
}
@Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable Direction facing) {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return true;
}
return super.hasCapability(capability, facing);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return (T) bloodAltar;
}
return super.getCapability(capability, facing);
}
}
// @Override
// public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable Direction facing)
// {
// if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
// {
// return true;
// }
//
// return super.hasCapability(capability, facing);
// }
//
// @SuppressWarnings("unchecked")
// @Override
// public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing)
// {
// if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
// {
// return (T) bloodAltar;
// }
//
// return super.getCapability(capability, facing);
// }
}

View file

@ -1,80 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.tile.base.TileBase;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
public class TileBloodTank extends TileBase {
public static final int[] CAPACITIES = {16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65336, 131072, 262144, 524288};
public int capacity;
protected FluidTank tank;
public TileBloodTank(int meta) {
capacity = CAPACITIES[meta] * Fluid.BUCKET_VOLUME;
tank = new FluidTank(capacity);
}
public TileBloodTank() {
capacity = CAPACITIES[0] * Fluid.BUCKET_VOLUME;
tank = new FluidTank(capacity);
}
@Override
public void deserialize(CompoundNBT tagCompound) {
super.deserialize(tagCompound);
tank.readFromNBT(tagCompound.getCompoundTag(Constants.NBT.TANK));
capacity = tagCompound.getInt(Constants.NBT.ALTAR_CAPACITY);
tank.setCapacity(capacity);
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
super.serialize(tagCompound);
if (tank.getFluidAmount() != 0)
tagCompound.putTag(Constants.NBT.TANK, tank.writeToNBT(new CompoundNBT()));
tagCompound.putInt(Constants.NBT.ALTAR_CAPACITY, capacity);
return tagCompound;
}
public int getCapacity() {
return capacity;
}
public FluidTank getTank() {
return tank;
}
public Fluid getClientRenderFluid() {
if (tank != null && tank.getFluid() != null)
return tank.getFluid().getFluid();
return null;
}
public float getRenderHeight() {
if (tank != null && tank.getFluidAmount() > 0)
return (float) tank.getFluidAmount() / (float) getCapacity();
return 0F;
}
public int getComparatorOutput() {
return tank.getFluidAmount() > 0 ? (int) (1 + ((double) tank.getFluidAmount() / (double) tank.getCapacity()) * 14) : 0;
}
@Override
public boolean hasCapability(Capability<?> capability, Direction facing) {
return capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, Direction facing) {
if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
return (T) tank;
return super.getCapability(capability, facing);
}
}

View file

@ -1,214 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.soul.IDemonWillConduit;
import WayofTime.bloodmagic.soul.IDemonWillGem;
import WayofTime.bloodmagic.soul.IDiscreteDemonWill;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import java.util.HashMap;
import java.util.Map.Entry;
public class TileDemonCrucible extends TileInventory implements ITickable, IDemonWillConduit, ISidedInventory {
public final int maxWill = 100;
public final double gemDrainRate = 10;
public HashMap<EnumDemonWillType, Double> willMap = new HashMap<>(); //TODO: Change to DemonWillHolder
public int internalCounter = 0;
public TileDemonCrucible() {
super(1, "demonCrucible");
}
@Override
public void update() {
if (getWorld().isRemote) {
return;
}
internalCounter++;
if (getWorld().isBlockPowered(getPos())) {
//TODO: Fill the contained gem if it is there.
ItemStack stack = this.getStackInSlot(0);
if (stack.getItem() instanceof IDemonWillGem) {
IDemonWillGem gemItem = (IDemonWillGem) stack.getItem();
for (EnumDemonWillType type : EnumDemonWillType.values()) {
if (willMap.containsKey(type)) {
double current = willMap.get(type);
double fillAmount = Math.min(gemDrainRate, current);
if (fillAmount > 0) {
fillAmount = gemItem.fillWill(type, stack, fillAmount, true);
if (willMap.get(type) - fillAmount <= 0) {
willMap.remove(type);
} else {
willMap.put(type, willMap.get(type) - fillAmount);
}
}
}
}
}
} else {
ItemStack stack = this.getStackInSlot(0);
if (!stack.isEmpty()) {
if (stack.getItem() instanceof IDemonWillGem) {
IDemonWillGem gemItem = (IDemonWillGem) stack.getItem();
for (EnumDemonWillType type : EnumDemonWillType.values()) {
double currentAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
double drainAmount = Math.min(maxWill - currentAmount, gemDrainRate);
double filled = WorldDemonWillHandler.fillWillToMaximum(getWorld(), pos, type, drainAmount, maxWill, false);
filled = gemItem.drainWill(type, stack, filled, false);
if (filled > 0) {
filled = gemItem.drainWill(type, stack, filled, true);
WorldDemonWillHandler.fillWillToMaximum(getWorld(), pos, type, filled, maxWill, true);
}
}
} else if (stack.getItem() instanceof IDiscreteDemonWill) //TODO: Limit the speed of this process
{
IDiscreteDemonWill willItem = (IDiscreteDemonWill) stack.getItem();
EnumDemonWillType type = willItem.getType(stack);
double currentAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
double needed = maxWill - currentAmount;
double discreteAmount = willItem.getDiscretization(stack);
if (needed >= discreteAmount) {
double filled = willItem.drainWill(stack, discreteAmount);
if (filled > 0) {
WorldDemonWillHandler.fillWillToMaximum(getWorld(), pos, type, filled, maxWill, true);
if (stack.getCount() <= 0) {
this.setInventorySlotContents(0, ItemStack.EMPTY);
}
}
}
}
}
}
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
willMap.clear();
for (EnumDemonWillType type : EnumDemonWillType.values()) {
double amount = tag.getDouble("EnumWill" + type.getName());
if (amount > 0) {
willMap.put(type, amount);
}
}
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
for (Entry<EnumDemonWillType, Double> entry : willMap.entrySet()) {
tag.putDouble("EnumWill" + entry.getKey().getName(), entry.getValue());
}
return tag;
}
// IDemonWillConduit
@Override
public int getWeight() {
return 10;
}
@Override
public double fillDemonWill(EnumDemonWillType type, double amount, boolean doFill) {
if (amount <= 0) {
return 0;
}
if (!canFill(type)) {
return 0;
}
if (!doFill) {
if (!willMap.containsKey(type)) {
return Math.min(maxWill, amount);
}
return Math.min(maxWill - willMap.get(type), amount);
}
if (!willMap.containsKey(type)) {
double max = Math.min(maxWill, amount);
willMap.put(type, max);
return max;
}
double current = willMap.get(type);
double filled = maxWill - current;
if (amount < filled) {
willMap.put(type, current + amount);
filled = amount;
} else {
willMap.put(type, (double) maxWill);
}
return filled;
}
@Override
public double drainDemonWill(EnumDemonWillType type, double amount, boolean doDrain) {
if (!willMap.containsKey(type)) {
return 0;
}
double drained = amount;
double current = willMap.get(type);
if (current < drained) {
drained = current;
}
if (doDrain) {
current -= drained;
if (current <= 0) {
willMap.remove(type);
} else {
willMap.put(type, current);
}
}
return drained;
}
@Override
public boolean canFill(EnumDemonWillType type) {
return true;
}
@Override
public boolean canDrain(EnumDemonWillType type) {
return true;
}
@Override
public double getCurrentWill(EnumDemonWillType type) {
return willMap.containsKey(type) ? willMap.get(type) : 0;
}
@Override
public int[] getSlotsForFace(Direction side) {
return new int[]{0};
}
@Override
public boolean canInsertItem(int index, ItemStack stack, Direction direction) {
return !stack.isEmpty() && inventory.get(0).isEmpty() && (stack.getItem() instanceof IDemonWillGem || stack.getItem() instanceof IDiscreteDemonWill);
}
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction) {
return true;
}
}

View file

@ -1,185 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.block.BlockDemonCrystal;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.soul.DemonWillHolder;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.tile.base.TileTicking;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
public class TileDemonCrystal extends TileTicking {
public static final double sameWillConversionRate = 50;
public static final double defaultWillConversionRate = 100;
public static final double timeDelayForWrongWill = 0.6;
public final int maxWill = 100;
public final double drainRate = 1;
public DemonWillHolder holder = new DemonWillHolder();
public double progressToNextCrystal = 0;
public int internalCounter = 0;
public int crystalCount = 1;
public Direction placement = Direction.UP; //Side that this crystal is placed on.
public TileDemonCrystal() {
this.crystalCount = 1;
}
@Override
public void onUpdate() {
if (getWorld().isRemote) {
return;
}
internalCounter++;
if (internalCounter % 20 == 0 && crystalCount < 7) {
EnumDemonWillType type = getType();
double value = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
if (type != EnumDemonWillType.DEFAULT) {
if (value >= 0.5) {
double nextProgress = getCrystalGrowthPerSecond(value);
progressToNextCrystal += WorldDemonWillHandler.drainWill(getWorld(), getPos(), type, nextProgress * sameWillConversionRate, true) / sameWillConversionRate;
} else {
value = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, EnumDemonWillType.DEFAULT);
if (value > 0.5) {
double nextProgress = getCrystalGrowthPerSecond(value) * timeDelayForWrongWill;
progressToNextCrystal += WorldDemonWillHandler.drainWill(getWorld(), getPos(), EnumDemonWillType.DEFAULT, nextProgress * defaultWillConversionRate, true) / defaultWillConversionRate;
}
}
} else {
if (value > 0.5) {
double nextProgress = getCrystalGrowthPerSecond(value);
progressToNextCrystal += WorldDemonWillHandler.drainWill(getWorld(), getPos(), type, nextProgress * sameWillConversionRate, true) / sameWillConversionRate;
}
}
checkAndGrowCrystal();
}
// if (getWorld().getWorldTime() % 200 == 0)
// {
// crystalCount = Math.min(crystalCount + 1, 7);
// getWorld().markBlockForUpdate(pos);
// }
}
/**
* Encourages the crystal to grow by a large percentage by telling it to
* drain will from the aura.
*
* @param willDrain The amount of drain that is needed for the crystal to grow
* successfully for the desired amount. Can be more than the base
* amount.
* @param progressPercentage
* @return percentage actually grown.
*/
public double growCrystalWithWillAmount(double willDrain, double progressPercentage) {
if (crystalCount >= 7) {
return 0;
}
BlockState state = getWorld().getBlockState(pos);
int meta = this.getBlockType().getMetaFromState(state);
EnumDemonWillType type = EnumDemonWillType.values()[meta];
double value = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
double percentDrain = willDrain <= 0 ? 1 : Math.min(1, value / willDrain);
if (percentDrain <= 0) {
return 0;
}
// Verification that you can actually drain the will from this chunk, for future proofing.
WorldDemonWillHandler.drainWill(getWorld(), pos, type, percentDrain * willDrain, true);
progressToNextCrystal += percentDrain * progressPercentage;
checkAndGrowCrystal();
return percentDrain * progressPercentage;
}
public EnumDemonWillType getType() {
return EnumDemonWillType.values()[this.getBlockMetadata()];
}
public void checkAndGrowCrystal() {
if (progressToNextCrystal >= 1 && internalCounter % 100 == 0) {
progressToNextCrystal--;
crystalCount++;
markDirty();
notifyUpdate();
}
}
public double getMaxWillForCrystal() {
return 50;
}
public boolean dropSingleCrystal() {
if (!getWorld().isRemote && crystalCount > 1) {
BlockState state = getWorld().getBlockState(pos);
EnumDemonWillType type = state.getValue(BlockDemonCrystal.TYPE);
ItemStack stack = BlockDemonCrystal.getItemStackDropped(type, 1);
if (!stack.isEmpty()) {
crystalCount--;
InventoryHelper.spawnItemStack(getWorld(), pos.getX(), pos.getY(), pos.getZ(), stack);
notifyUpdate();
return true;
}
}
return false;
}
public double getCrystalGrowthPerSecond(double will) {
return 1.0 / 200 * Math.sqrt(will / 200);
}
public int getCrystalCountForRender() {
return MathHelper.clamp(crystalCount - 1, 0, 6);
}
@Override
public void deserialize(CompoundNBT tag) {
holder.readFromNBT(tag, "Will");
crystalCount = tag.getInt("crystalCount");
placement = Direction.byIndex(tag.getInt("placement"));
progressToNextCrystal = tag.getDouble("progress");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
holder.writeToNBT(tag, "Will");
tag.putInt("crystalCount", crystalCount);
tag.putInt("placement", placement.getIndex());
tag.putDouble("progress", progressToNextCrystal);
return tag;
}
public int getCrystalCount() {
return crystalCount;
}
public void setCrystalCount(int crystalCount) {
this.crystalCount = crystalCount;
}
public Direction getPlacement() {
return placement;
}
public void setPlacement(Direction placement) {
this.placement = placement;
}
@Override
protected void onDataPacketClientReceived() {
super.onDataPacketClientReceived();
notifyUpdate();
}
}

View file

@ -1,133 +0,0 @@
package WayofTime.bloodmagic.tile;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.soul.DemonWillHolder;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.soul.IDemonWillConduit;
import WayofTime.bloodmagic.tile.base.TileTicking;
public class TileDemonCrystallizer extends TileTicking implements IDemonWillConduit {
public static final int maxWill = 100;
public static final double drainRate = 1;
public static final double willToFormCrystal = 99;
public static final double totalFormationTime = 1000;
//The whole purpose of this block is to grow a crystal initially. The acceleration and crystal growing is up to the crystal itself afterwards.
public DemonWillHolder holder = new DemonWillHolder();
public double internalCounter = 0;
public TileDemonCrystallizer() {
}
@Override
public void onUpdate() {
if (getWorld().isRemote) {
return;
}
BlockPos offsetPos = pos.offset(Direction.UP);
if (getWorld().isAirBlock(offsetPos)) //Room for a crystal to grow
{
EnumDemonWillType highestType = WorldDemonWillHandler.getHighestDemonWillType(getWorld(), pos);
double amount = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, highestType);
if (amount >= willToFormCrystal) {
internalCounter += getCrystalFormationRate(amount);
if (internalCounter >= totalFormationTime) {
if (WorldDemonWillHandler.drainWill(getWorld(), getPos(), highestType, willToFormCrystal, false) >= willToFormCrystal) {
if (formCrystal(highestType, offsetPos)) {
WorldDemonWillHandler.drainWill(getWorld(), getPos(), highestType, willToFormCrystal, true);
internalCounter = 0;
}
}
}
}
}
}
public boolean formCrystal(EnumDemonWillType type, BlockPos position) {
getWorld().setBlockState(position, RegistrarBloodMagicBlocks.DEMON_CRYSTAL.getStateFromMeta(type.ordinal()));
TileEntity tile = getWorld().getTileEntity(position);
if (tile instanceof TileDemonCrystal) {
((TileDemonCrystal) tile).setPlacement(Direction.UP);
return true;
}
return false;
}
public double getCrystalFormationRate(double currentWill) {
return 1;
}
@Override
public void deserialize(CompoundNBT tag) {
holder.readFromNBT(tag, "Will");
internalCounter = tag.getDouble("internalCounter");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
holder.writeToNBT(tag, "Will");
tag.putDouble("internalCounter", internalCounter);
return tag;
}
// IDemonWillConduit
@Override
public int getWeight() {
return 10;
}
@Override
public double fillDemonWill(EnumDemonWillType type, double amount, boolean doFill) {
if (amount <= 0) {
return 0;
}
if (!canFill(type)) {
return 0;
}
if (!doFill) {
return Math.min(maxWill - holder.getWill(type), amount);
}
return holder.addWill(type, amount, maxWill);
}
@Override
public double drainDemonWill(EnumDemonWillType type, double amount, boolean doDrain) {
double drained = amount;
double current = holder.getWill(type);
if (current < drained) {
drained = current;
}
if (doDrain) {
return holder.drainWill(type, amount);
}
return drained;
}
@Override
public boolean canFill(EnumDemonWillType type) {
return true;
}
@Override
public boolean canDrain(EnumDemonWillType type) {
return true;
}
@Override
public double getCurrentWill(EnumDemonWillType type) {
return holder.getWill(type);
}
}

View file

@ -1,106 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.soul.DemonWillHolder;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.soul.IDemonWillConduit;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.tile.base.TileTicking;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
public class TileDemonPylon extends TileTicking implements IDemonWillConduit {
public final int maxWill = 100;
public final double drainRate = 1;
public DemonWillHolder holder = new DemonWillHolder();
public TileDemonPylon() {
}
@Override
public void onUpdate() {
if (getWorld().isRemote) {
return;
}
for (EnumDemonWillType type : EnumDemonWillType.values()) {
double currentAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
for (Direction side : Direction.HORIZONTALS) {
BlockPos offsetPos = pos.offset(side, 16);
double sideAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), offsetPos, type);
if (sideAmount > currentAmount) {
double drainAmount = Math.min((sideAmount - currentAmount) / 2, drainRate);
double drain = WorldDemonWillHandler.drainWill(getWorld(), offsetPos, type, drainAmount, true);
WorldDemonWillHandler.fillWill(getWorld(), pos, type, drain, true);
}
}
}
}
@Override
public void deserialize(CompoundNBT tag) {
holder.readFromNBT(tag, "Will");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
holder.writeToNBT(tag, "Will");
return tag;
}
// IDemonWillConduit
@Override
public int getWeight() {
return 10;
}
@Override
public double fillDemonWill(EnumDemonWillType type, double amount, boolean doFill) {
if (amount <= 0) {
return 0;
}
if (!canFill(type)) {
return 0;
}
if (!doFill) {
return Math.min(maxWill - holder.getWill(type), amount);
}
return holder.addWill(type, amount, maxWill);
}
@Override
public double drainDemonWill(EnumDemonWillType type, double amount, boolean doDrain) {
double drained = amount;
double current = holder.getWill(type);
if (current < drained) {
drained = current;
}
if (doDrain) {
return holder.drainWill(type, amount);
}
return drained;
}
@Override
public boolean canFill(EnumDemonWillType type) {
return true;
}
@Override
public boolean canDrain(EnumDemonWillType type) {
return true;
}
@Override
public double getCurrentWill(EnumDemonWillType type) {
return holder.getWill(type);
}
}

View file

@ -1,41 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.ritual.types.RitualPortal;
import WayofTime.bloodmagic.tile.base.TileBase;
import com.google.common.base.Strings;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.math.BlockPos;
public class TileDimensionalPortal extends TileBase {
public String portalID = "";
public int masterStoneX;
public int masterStoneY;
public int masterStoneZ;
public void deserialize(CompoundNBT tagCompound) {
portalID = tagCompound.getString(RitualPortal.PORTAL_ID_TAG);
masterStoneX = tagCompound.getInt("masterStoneX");
masterStoneY = tagCompound.getInt("masterStoneY");
masterStoneZ = tagCompound.getInt("masterStoneZ");
}
public CompoundNBT serialize(CompoundNBT tagCompound) {
tagCompound.putString(RitualPortal.PORTAL_ID_TAG, Strings.isNullOrEmpty(portalID) ? "" : portalID);
tagCompound.putInt("masterStoneX", masterStoneX);
tagCompound.putInt("masterStoneY", masterStoneY);
tagCompound.putInt("masterStoneZ", masterStoneZ);
return tagCompound;
}
public BlockPos getMasterStonePos() {
return new BlockPos(masterStoneX, masterStoneY, masterStoneZ);
}
public void setMasterStonePos(BlockPos blockPos) {
this.masterStoneX = blockPos.getX();
this.masterStoneY = blockPos.getY();
this.masterStoneZ = blockPos.getZ();
}
}

View file

@ -1,46 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.BloodMagic;
import WayofTime.bloodmagic.core.data.SoulTicket;
import WayofTime.bloodmagic.ritual.imperfect.IImperfectRitualStone;
import WayofTime.bloodmagic.ritual.imperfect.ImperfectRitual;
import WayofTime.bloodmagic.tile.base.TileBase;
import WayofTime.bloodmagic.util.helper.NetworkHelper;
import WayofTime.bloodmagic.util.helper.PlayerHelper;
import net.minecraft.entity.effect.LightningBoltEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public class TileImperfectRitualStone extends TileBase implements IImperfectRitualStone {
@Override
public boolean performRitual(World world, BlockPos pos, @Nullable ImperfectRitual imperfectRitual, PlayerEntity player) {
if (imperfectRitual != null && BloodMagic.RITUAL_MANAGER.enabled(BloodMagic.RITUAL_MANAGER.getId(imperfectRitual), true)) {
if (!PlayerHelper.isFakePlayer(player) && !world.isRemote) {
NetworkHelper.getSoulNetwork(player).syphonAndDamage(player, SoulTicket.block(getWorld(), getPos(), imperfectRitual.getActivationCost()));
if (imperfectRitual.onActivate(this, player)) {
if (imperfectRitual.isLightShow())
getWorld().addWeatherEffect(new LightningBoltEntity(getWorld(), getPos().getX(), getPos().getY() + 2, getPos().getZ(), true));
return true;
}
}
return true;
}
return false;
}
@Override
public World getRitualWorld() {
return getWorld();
}
@Override
public BlockPos getRitualPos() {
return getPos();
}
}

View file

@ -1,160 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.ritual.AreaDescriptor;
import WayofTime.bloodmagic.util.helper.PlayerSacrificeHelper;
import WayofTime.bloodmagic.incense.*;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ServerWorld;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class TileIncenseAltar extends TileInventory implements ITickable {
public static int maxCheckRange = 5;
public AreaDescriptor incenseArea = new AreaDescriptor.Rectangle(new BlockPos(-5, -5, -5), 11);
public Map<EnumTranquilityType, Double> tranquilityMap = new HashMap<>();
public double incenseAddition = 0; //Self-sacrifice is multiplied by 1 plus this value.
public double tranquility = 0;
public int roadDistance = 0; //Number of road blocks laid down
public TileIncenseAltar() {
super(1, "incenseAltar");
}
@Override
public void update() {
AxisAlignedBB aabb = incenseArea.getAABB(getPos());
List<PlayerEntity> playerList = getWorld().getEntitiesWithinAABB(PlayerEntity.class, aabb);
if (playerList.isEmpty()) {
return;
}
if (getWorld().getTotalWorldTime() % 100 == 0) {
recheckConstruction();
}
boolean hasPerformed = false;
for (PlayerEntity player : playerList) {
if (PlayerSacrificeHelper.incrementIncense(player, 0, incenseAddition, incenseAddition / 100)) {
hasPerformed = true;
}
}
if (hasPerformed) {
if (getWorld().rand.nextInt(4) == 0 && getWorld() instanceof ServerWorld) {
ServerWorld server = (ServerWorld) getWorld();
server.spawnParticle(EnumParticleTypes.FLAME, pos.getX() + 0.5, pos.getY() + 1.2, pos.getZ() + 0.5, 1, 0.02, 0.03, 0.02, 0);
}
}
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
tranquility = tag.getDouble("tranquility");
incenseAddition = tag.getDouble("incenseAddition");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putDouble("tranquility", tranquility);
tag.putDouble("incenseAddition", incenseAddition);
return tag;
}
public void recheckConstruction() {
//TODO: Check the physical construction of the incense altar to determine the maximum length.
int maxLength = 11; //Max length of the path. The path starts two blocks away from the center block.
int yOffset = 0;
Map<EnumTranquilityType, Double> tranquilityMap = new HashMap<>();
for (int currentDistance = 2; currentDistance < currentDistance + maxLength; currentDistance++) {
boolean canFormRoad = false;
for (int i = -maxCheckRange + yOffset; i <= maxCheckRange + yOffset; i++) {
BlockPos verticalPos = pos.add(0, i, 0);
canFormRoad = true;
level:
for (Direction horizontalFacing : Direction.HORIZONTALS) {
BlockPos facingOffsetPos = verticalPos.offset(horizontalFacing, currentDistance);
for (int j = -1; j <= 1; j++) {
BlockPos offsetPos = facingOffsetPos.offset(horizontalFacing.rotateY(), j);
BlockState state = getWorld().getBlockState(offsetPos);
Block block = state.getBlock();
if (!(block instanceof IIncensePath && ((IIncensePath) block).getLevelOfPath(getWorld(), offsetPos, state) >= currentDistance - 2)) {
canFormRoad = false;
break level;
}
}
}
if (canFormRoad) {
yOffset = i;
break;
}
}
if (canFormRoad) {
for (int i = -currentDistance; i <= currentDistance; i++) {
for (int j = -currentDistance; j <= currentDistance; j++) {
if (Math.abs(i) != currentDistance && Math.abs(j) != currentDistance) {
continue; //TODO: Can make this just set j to currentDistance to speed it up.
}
for (int y = yOffset; y <= 2 + yOffset; y++) {
BlockPos offsetPos = pos.add(i, y, j);
BlockState state = getWorld().getBlockState(offsetPos);
Block block = state.getBlock();
TranquilityStack stack = IncenseTranquilityRegistry.getTranquilityOfBlock(getWorld(), offsetPos, block, state);
if (stack != null) {
if (!tranquilityMap.containsKey(stack.type)) {
tranquilityMap.put(stack.type, stack.value);
} else {
tranquilityMap.put(stack.type, tranquilityMap.get(stack.type) + stack.value);
}
}
}
}
}
} else {
roadDistance = currentDistance - 2;
break;
}
}
this.tranquilityMap = tranquilityMap;
double totalTranquility = 0;
for (Entry<EnumTranquilityType, Double> entry : tranquilityMap.entrySet()) {
totalTranquility += entry.getValue();
}
if (totalTranquility < 0) {
return;
}
double appliedTranquility = 0;
for (Entry<EnumTranquilityType, Double> entry : tranquilityMap.entrySet()) {
appliedTranquility += Math.sqrt(entry.getValue());
}
double bonus = IncenseAltarHandler.getIncenseBonusFromComponents(getWorld(), pos, appliedTranquility, roadDistance);
incenseAddition = bonus;
this.tranquility = appliedTranquility;
}
}

View file

@ -1,261 +1,317 @@
package WayofTime.bloodmagic.tile;
package wayoftime.bloodmagic.tile;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import WayofTime.bloodmagic.tile.base.TileBase;
import WayofTime.bloodmagic.util.helper.TextHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.NonNullList;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import wayoftime.bloodmagic.tile.base.TileBase;
public class TileInventory extends TileBase implements IInventory {
protected int[] syncedSlots = new int[0];
protected NonNullList<ItemStack> inventory;
IItemHandler handlerDown;
IItemHandler handlerUp;
IItemHandler handlerNorth;
IItemHandler handlerSouth;
IItemHandler handlerWest;
IItemHandler handlerEast;
private int size;
public class TileInventory extends TileBase implements IInventory
{
protected int[] syncedSlots = new int[0];
protected NonNullList<ItemStack> inventory;
LazyOptional<IItemHandler> handlerDown;
LazyOptional<IItemHandler> handlerUp;
LazyOptional<IItemHandler> handlerNorth;
LazyOptional<IItemHandler> handlerSouth;
LazyOptional<IItemHandler> handlerWest;
LazyOptional<IItemHandler> handlerEast;
private int size;
// IInventory
private String name;
// IInventory
private String name;
public TileInventory(int size, String name) {
this.inventory = NonNullList.withSize(size, ItemStack.EMPTY);
this.size = size;
this.name = name;
initializeItemHandlers();
}
public TileInventory(TileEntityType<?> type, int size, String name)
{
super(type);
this.inventory = NonNullList.withSize(size, ItemStack.EMPTY);
this.size = size;
this.name = name;
initializeItemHandlers();
}
protected boolean isSyncedSlot(int slot) {
for (int s : this.syncedSlots) {
if (s == slot) {
return true;
}
}
return false;
}
protected boolean isSyncedSlot(int slot)
{
for (int s : this.syncedSlots)
{
if (s == slot)
{
return true;
}
}
return false;
}
@Override
public void deserialize(CompoundNBT tagCompound) {
super.deserialize(tagCompound);
ListNBT tags = tagCompound.getTagList("Items", 10);
inventory = NonNullList.withSize(size, ItemStack.EMPTY);
@Override
public void deserialize(CompoundNBT tagCompound)
{
super.deserialize(tagCompound);
for (int i = 0; i < tags.tagCount(); i++) {
if (!isSyncedSlot(i)) {
CompoundNBT data = tags.getCompound(i);
byte j = data.getByte("Slot");
this.inventory = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY);
if (j >= 0 && j < inventory.size()) {
inventory.set(j, new ItemStack(data)); // No matter how much an i looks like a j, it is not one. They are drastically different characters and cause drastically different things to happen. Apparently I didn't know this at one point. - TehNut
}
}
}
}
ItemStackHelper.loadAllItems(tagCompound, this.inventory);
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
super.serialize(tagCompound);
ListNBT tags = new ListNBT();
// ListNBT tags = tagCompound.getList("Items", 10);
// inventory = NonNullList.withSize(size, ItemStack.EMPTY);
//
//
//
// for (int i = 0; i < tags.size(); i++)
// {
// if (!isSyncedSlot(i))
// {
// CompoundNBT data = tags.getCompoundTagAt(i);
// byte j = data.getByte("Slot");
//
// if (j >= 0 && j < inventory.size())
// {
// inventory.set(j, new ItemStack(data)); // No matter how much an i looks like a j, it is not one.
// // They are drastically different characters and cause
// // drastically different things to happen. Apparently I
// // didn't know this at one point. - TehNut
// }
// }
// }
}
for (int i = 0; i < inventory.size(); i++) {
if ((!inventory.get(i).isEmpty()) && !isSyncedSlot(i)) {
CompoundNBT data = new CompoundNBT();
data.setByte("Slot", (byte) i);
inventory.get(i).writeToNBT(data);
tags.appendTag(data);
}
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound)
{
super.serialize(tagCompound);
tagCompound.putTag("Items", tags);
return tagCompound;
}
ItemStackHelper.saveAllItems(tagCompound, this.inventory);
// NBTTagList tags = new NBTTagList();
//
// for (int i = 0; i < inventory.size(); i++)
// {
// if ((!inventory.get(i).isEmpty()) && !isSyncedSlot(i))
// {
// CompoundNBT data = new CompoundNBT();
// data.putByte("Slot", (byte) i);
// inventory.get(i).write(data);
// tags.appendTag(data);
// }
// }
//
// tagCompound.setTag("Items", tags);
return tagCompound;
}
public void dropItems() {
InventoryHelper.dropInventoryItems(getWorld(), getPos(), this);
}
public void dropItems()
{
InventoryHelper.dropInventoryItems(getWorld(), getPos(), this);
}
@Override
public int getSizeInventory() {
return size;
}
@Override
public int getSizeInventory()
{
return size;
}
@Override
public ItemStack getStackInSlot(int index) {
return inventory.get(index);
}
@Override
public ItemStack getStackInSlot(int index)
{
return inventory.get(index);
}
@Override
public ItemStack decrStackSize(int index, int count) {
if (!getStackInSlot(index).isEmpty()) {
if (!getWorld().isRemote)
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
@Override
public ItemStack decrStackSize(int index, int count)
{
if (!getStackInSlot(index).isEmpty())
{
if (!getWorld().isRemote)
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
if (getStackInSlot(index).getCount() <= count) {
ItemStack itemStack = inventory.get(index);
inventory.set(index, ItemStack.EMPTY);
markDirty();
return itemStack;
}
if (getStackInSlot(index).getCount() <= count)
{
ItemStack itemStack = inventory.get(index);
inventory.set(index, ItemStack.EMPTY);
markDirty();
return itemStack;
}
ItemStack itemStack = inventory.get(index).splitStack(count);
markDirty();
return itemStack;
}
ItemStack itemStack = inventory.get(index).split(count);
markDirty();
return itemStack;
}
return ItemStack.EMPTY;
}
return ItemStack.EMPTY;
}
@Override
public ItemStack removeStackFromSlot(int slot) {
if (!inventory.get(slot).isEmpty()) {
ItemStack itemStack = inventory.get(slot);
setInventorySlotContents(slot, ItemStack.EMPTY);
return itemStack;
}
return ItemStack.EMPTY;
}
@Override
public ItemStack removeStackFromSlot(int slot)
{
if (!inventory.get(slot).isEmpty())
{
ItemStack itemStack = inventory.get(slot);
setInventorySlotContents(slot, ItemStack.EMPTY);
return itemStack;
}
return ItemStack.EMPTY;
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack) {
inventory.set(slot, stack);
if (!stack.isEmpty() && stack.getCount() > getInventoryStackLimit())
stack.setCount(getInventoryStackLimit());
markDirty();
if (!getWorld().isRemote)
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack)
{
inventory.set(slot, stack);
if (!stack.isEmpty() && stack.getCount() > getInventoryStackLimit())
stack.setCount(getInventoryStackLimit());
markDirty();
if (!getWorld().isRemote)
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public void openInventory(PlayerEntity player) {
@Override
public void openInventory(PlayerEntity player)
{
}
}
@Override
public void closeInventory(PlayerEntity player) {
@Override
public void closeInventory(PlayerEntity player)
{
}
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
return true;
}
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{
return true;
}
// IWorldNameable
// IWorldNameable
@Override
public int getField(int id) {
return 0;
}
// @Override
// public int getField(int id)
// {
// return 0;
// }
//
// @Override
// public void setField(int id, int value)
// {
//
// }
//
// @Override
// public int getFieldCount()
// {
// return 0;
// }
@Override
public void setField(int id, int value) {
@Override
public void clear()
{
this.inventory = NonNullList.withSize(size, ItemStack.EMPTY);
}
}
@Override
public boolean isEmpty()
{
for (ItemStack stack : inventory) if (!stack.isEmpty())
return false;
@Override
public int getFieldCount() {
return 0;
}
return true;
}
@Override
public void clear() {
this.inventory = NonNullList.withSize(size, ItemStack.EMPTY);
}
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{
return true;
}
@Override
public boolean isEmpty() {
for (ItemStack stack : inventory)
if (!stack.isEmpty())
return false;
// @Override
// public String getName()
// {
// return TextHelper.localize("tile.bloodmagic." + name + ".name");
// }
//
// @Override
// public boolean hasCustomName()
// {
// return true;
// }
//
// @Override
// public ITextComponent getDisplayName()
// {
// return new TextComponentString(getName());
// }
return true;
}
protected void initializeItemHandlers()
{
if (this instanceof ISidedInventory)
{
handlerDown = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
handlerUp = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
handlerNorth = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
handlerSouth = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
handlerWest = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
handlerEast = LazyOptional.of(() -> new SidedInvWrapper((ISidedInventory) this, Direction.DOWN));
} else
{
handlerDown = LazyOptional.of(() -> new InvWrapper(this));
handlerUp = handlerDown;
handlerNorth = handlerDown;
handlerSouth = handlerDown;
handlerWest = handlerDown;
handlerEast = handlerDown;
}
}
@Override
public boolean isUsableByPlayer(PlayerEntity player) {
return true;
}
@SuppressWarnings("unchecked")
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing)
{
if (facing != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
{
switch (facing)
{
case DOWN:
return handlerDown.cast();
case EAST:
return handlerEast.cast();
case NORTH:
return handlerNorth.cast();
case SOUTH:
return handlerSouth.cast();
case UP:
return handlerUp.cast();
case WEST:
return handlerWest.cast();
}
} else if (facing == null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
{
return handlerDown.cast();
}
@Override
public String getName() {
return TextHelper.localize("tile.bloodmagic." + name + ".name");
}
return super.getCapability(capability, facing);
}
@Override
public boolean hasCustomName() {
return true;
}
@Override
public ITextComponent getDisplayName() {
return new StringTextComponent(getName());
}
protected void initializeItemHandlers() {
if (this instanceof ISidedInventory) {
handlerDown = new SidedInvWrapper((ISidedInventory) this, Direction.DOWN);
handlerUp = new SidedInvWrapper((ISidedInventory) this, Direction.UP);
handlerNorth = new SidedInvWrapper((ISidedInventory) this, Direction.NORTH);
handlerSouth = new SidedInvWrapper((ISidedInventory) this, Direction.SOUTH);
handlerWest = new SidedInvWrapper((ISidedInventory) this, Direction.WEST);
handlerEast = new SidedInvWrapper((ISidedInventory) this, Direction.EAST);
} else {
handlerDown = new InvWrapper(this);
handlerUp = handlerDown;
handlerNorth = handlerDown;
handlerSouth = handlerDown;
handlerWest = handlerDown;
handlerEast = handlerDown;
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T getCapability(Capability<T> capability, Direction facing) {
if (facing != null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
switch (facing) {
case DOWN:
return (T) handlerDown;
case EAST:
return (T) handlerEast;
case NORTH:
return (T) handlerNorth;
case SOUTH:
return (T) handlerSouth;
case UP:
return (T) handlerUp;
case WEST:
return (T) handlerWest;
}
} else if (facing == null && capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return (T) handlerDown;
}
return super.getCapability(capability, facing);
}
@Override
public boolean hasCapability(Capability<?> capability, Direction facing) {
return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
}
}
// @Override
// public boolean hasCapability(Capability<?> capability, Direction facing)
// {
// return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
// }
}

View file

@ -1,532 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.BloodMagic;
import WayofTime.bloodmagic.util.BMLog;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.inversion.InversionPillarHandler;
import WayofTime.bloodmagic.tile.base.TileTicking;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.animation.Event;
import net.minecraftforge.common.animation.TimeValues.VariableValue;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.model.animation.CapabilityAnimation;
import net.minecraftforge.common.model.animation.IAnimationStateMachine;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public class TileInversionPillar extends TileTicking {
public static final double maxWillForChunk = 1000;
public static double willPerOperation = 0.5;
public static double inversionPerOperation = 4;
public static double addedInversionPerFailedCheck = 1;
public static double inversionToIncreaseRadius = 100;
public static double inversionToAddPillar = 200;
public static double operationThreshold = 20;
public static double inversionToSpreadWill = 200;
public static double willPushRate = 1;
public static double inversionCostPerWillSpread = 4;
public static double minimumWillForChunkWhenSpreading = 100;
private final IAnimationStateMachine asm;
private final VariableValue animationOffset = new VariableValue(0);
private final VariableValue cycleLength = new VariableValue(4);
public EnumDemonWillType type;
public double currentInversion = 0;
public int consecutiveFailedChecks = 0; //If you fail enough checks, increase the radius.
public int consecutiveFailedAirChecks = 0;
public int currentInfectionRadius = 1;
// public int dormantCounter = 0; //Time that the pillar will
public int counter = 0;
public boolean isRegistered = false;
private float animationOffsetValue = 0;
public TileInversionPillar() {
this(EnumDemonWillType.DEFAULT);
}
public TileInversionPillar(EnumDemonWillType type) {
this.type = type;
asm = BloodMagic.proxy.load(new ResourceLocation(BloodMagic.MODID.toLowerCase(), "asms/block/inversion_pillar.json"), ImmutableMap.of("offset", animationOffset, "cycle_length", cycleLength));
animationOffsetValue = -1;
}
@Override
public void onUpdate() {
if (animationOffsetValue < 0) {
animationOffsetValue = getWorld().getTotalWorldTime() * getWorld().rand.nextFloat();
animationOffset.setValue(animationOffsetValue);
}
if (getWorld().isRemote) {
return;
}
if (!isRegistered) {
isRegistered = InversionPillarHandler.addPillarToMap(getWorld(), getType(), getPos());
}
counter++;
double currentWill = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
if (counter % 1 == 0) {
List<BlockPos> pillarList = getNearbyPillarsExcludingThis();
// if (type == EnumDemonWillType.VENGEFUL)
// {
// System.out.println(pillarList.size() + " nearby pillars");
// }
generateWillForNearbyPillars(currentWill, pillarList);
generateInversionForNearbyPillars(currentWill, pillarList);
int pollute = polluteNearbyBlocks(currentWill);
if (pollute == 1) {
currentInversion += addedInversionPerFailedCheck;
consecutiveFailedChecks++;
} else if (pollute == 3) {
currentInversion += addedInversionPerFailedCheck;
consecutiveFailedAirChecks++;
} else if (pollute == 0) {
//We successfully found a block to replace!
consecutiveFailedChecks = 0;
consecutiveFailedAirChecks = 0;
}
if (consecutiveFailedAirChecks > 100) {
createObstructionsInAir();
}
if (currentInversion >= inversionToSpreadWill) {
spreadWillToSurroundingChunks();
}
if (consecutiveFailedChecks > 5 * currentInfectionRadius && currentInversion >= inversionToIncreaseRadius) {
currentInfectionRadius++;
consecutiveFailedChecks = 0;
currentInversion -= inversionToIncreaseRadius;
BMLog.DEBUG.info("Increasing radius!");
} else if (consecutiveFailedAirChecks > 25 * currentInfectionRadius) //Change this to require a number of "creations" with the orbs in the air.
{
currentInfectionRadius++;
consecutiveFailedChecks = 0;
currentInversion -= inversionToIncreaseRadius;
BMLog.DEBUG.info("Increasing radius due to being in the air!");
}
if (currentInfectionRadius >= 8 && currentInversion >= inversionToAddPillar) {
//TODO: Improve algorithm
List<BlockPos> allConnectedPos = InversionPillarHandler.getAllConnectedPillars(getWorld(), type, pos);
BlockPos candidatePos = findCandidatePositionForPillar(getWorld(), type, pos, allConnectedPos, 5, 10);
if (!candidatePos.equals(BlockPos.ORIGIN)) {
currentInversion = 0;
BlockState pillarState = RegistrarBloodMagicBlocks.INVERSION_PILLAR.getStateFromMeta(type.ordinal());
BlockState bottomState = RegistrarBloodMagicBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2);
BlockState topState = RegistrarBloodMagicBlocks.INVERSION_PILLAR_END.getStateFromMeta(type.ordinal() * 2 + 1);
getWorld().setBlockState(candidatePos, pillarState);
getWorld().setBlockState(candidatePos.down(), bottomState);
getWorld().setBlockState(candidatePos.up(), topState);
}
}
}
}
// public static int getDormantTimeForConnectedPillarsOnSpawn()
// {
// return 0;
// }
public void createObstructionsInAir() {
if (currentInversion > 1000) {
Vec3d vec = new Vec3d(getWorld().rand.nextDouble() * 2 - 1, getWorld().rand.nextDouble() * 2 - 1, getWorld().rand.nextDouble() * 2 - 1).normalize().scale(2 * currentInfectionRadius);
BlockPos centralPos = pos.add(vec.x, vec.y, vec.z);
getWorld().setBlockState(centralPos, RegistrarBloodMagicBlocks.DEMON_EXTRAS.getStateFromMeta(0));
currentInversion -= 1000;
}
}
public void spreadWillToSurroundingChunks() {
double currentAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
if (currentAmount <= minimumWillForChunkWhenSpreading) {
return;
}
for (Direction side : Direction.HORIZONTALS) {
BlockPos offsetPos = pos.offset(side, 16);
double sideAmount = WorldDemonWillHandler.getCurrentWill(getWorld(), offsetPos, type);
if (currentAmount > sideAmount) {
double drainAmount = Math.min((currentAmount - sideAmount) / 2, willPushRate);
if (drainAmount < willPushRate / 2) {
continue;
}
double drain = WorldDemonWillHandler.drainWill(getWorld(), pos, type, drainAmount, true);
drain = WorldDemonWillHandler.fillWillToMaximum(getWorld(), offsetPos, type, drain, maxWillForChunk, true);
currentInversion -= drain * inversionCostPerWillSpread;
}
}
}
public void removePillarFromMap() {
if (!getWorld().isRemote) {
InversionPillarHandler.removePillarFromMap(getWorld(), type, pos);
}
}
public List<BlockPos> getNearbyPillarsExcludingThis() {
return InversionPillarHandler.getNearbyPillars(getWorld(), type, pos);
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
if (!tag.hasKey(Constants.NBT.WILL_TYPE)) {
type = EnumDemonWillType.DEFAULT;
}
type = EnumDemonWillType.valueOf(tag.getString(Constants.NBT.WILL_TYPE).toUpperCase(Locale.ENGLISH));
currentInversion = tag.getDouble("currentInversion");
currentInfectionRadius = tag.getInt("currentInfectionRadius");
consecutiveFailedChecks = tag.getInt("consecutiveFailedChecks");
animationOffsetValue = tag.getFloat("animationOffset");
animationOffset.setValue(animationOffsetValue);
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putString(Constants.NBT.WILL_TYPE, type.toString());
tag.putDouble("currentInversion", currentInversion);
tag.putInt("currentInfectionRadius", currentInfectionRadius);
tag.putInt("consecutiveFailedChecks", consecutiveFailedChecks);
tag.putFloat("animationOffset", animationOffsetValue);
return tag;
}
public void generateWillForNearbyPillars(double currentWillInChunk, List<BlockPos> offsetPositions) {
double totalGeneratedWill = 0;
double willFactor = currentWillInChunk / 1000;
for (BlockPos offsetPos : offsetPositions) {
double distanceSquared = offsetPos.distanceSq(pos);
totalGeneratedWill += willFactor * 343 / (343 + Math.pow(distanceSquared, 3 / 2));
}
if (totalGeneratedWill > 0) {
WorldDemonWillHandler.fillWillToMaximum(getWorld(), pos, type, totalGeneratedWill, maxWillForChunk, true);
}
}
public void generateInversionForNearbyPillars(double currentWillInChunk, List<BlockPos> offsetPositions) {
double willFactor = currentWillInChunk / 400;
double totalGeneratedInversion = willFactor;
for (BlockPos offsetPos : offsetPositions) {
double distanceSquared = offsetPos.distanceSq(pos);
totalGeneratedInversion += 3125 / (3125 + Math.pow(distanceSquared, 5 / 2));
}
currentInversion = Math.max(0, currentInversion + totalGeneratedInversion);
}
/**
* @param currentWillInChunk
* @return 0 if the block is successfully placed, 1 if the block is not
* placed due to the selected place being invalid, 2 if the block is
* not placed due to there not being enough Will or Inversion, 3 if
* the block is not placed due to the selected block being air.
*/
public int polluteNearbyBlocks(double currentWillInChunk) {
// System.out.println("Hai! :D Current Inversion: " + currentInversion + ", Current Will: " + currentWillInChunk);
if (currentWillInChunk < operationThreshold || currentInversion < inversionPerOperation) {
return 2; //Not enough Will or Inversion available
}
for (int i = 0; i < currentInfectionRadius; i++) {
double xOff = (getWorld().rand.nextBoolean() ? 1 : -1) * (getWorld().rand.nextGaussian() + 1) * (currentInfectionRadius);
double yOff = (getWorld().rand.nextBoolean() ? 1 : -1) * (getWorld().rand.nextGaussian() + 1) * (currentInfectionRadius);
double zOff = (getWorld().rand.nextBoolean() ? 1 : -1) * (getWorld().rand.nextGaussian() + 1) * (currentInfectionRadius);
double r2 = xOff * xOff + yOff * yOff + zOff * zOff;
int maxInfectionRadius2 = (9 * currentInfectionRadius * currentInfectionRadius);
if (r2 > maxInfectionRadius2) {
double factor = Math.sqrt(maxInfectionRadius2 / r2);
xOff *= factor;
yOff *= factor;
zOff *= factor;
}
BlockPos offsetPos = pos.add(xOff + 0.5, yOff + 0.5, zOff + 0.5);
if (offsetPos.equals(pos)) {
return 1; //Invalid block (itself!)
}
BlockState state = getWorld().getBlockState(offsetPos);
if (!state.getBlock().isAir(state, getWorld(), offsetPos)) {
//Consume Will and set this block
Block block = state.getBlock();
if (block == Blocks.DIRT || block == Blocks.STONE || block == Blocks.GRASS) {
if (getWorld().setBlockState(offsetPos, RegistrarBloodMagicBlocks.DEMON_EXTRAS.getStateFromMeta(0))) {
WorldDemonWillHandler.drainWill(getWorld(), pos, type, willPerOperation, true);
currentInversion -= inversionPerOperation;
return 0; //Successfully placed
}
}
return 1; //Invalid block
}
}
return 3; //The block was air
}
public void handleEvents(float time, Iterable<Event> pastEvents) {
for (Event event : pastEvents) {
BMLog.DEBUG.info("Event: " + event.event() + " " + event.offset() + " " + getPos() + " " + time);
}
}
@Override
public boolean hasFastRenderer() {
return true;
}
@Override
public boolean hasCapability(Capability<?> capability, Direction side) {
if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) {
return true;
}
return super.hasCapability(capability, side);
}
@Override
public <T> T getCapability(Capability<T> capability, Direction side) {
if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) {
return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
}
return super.getCapability(capability, side);
}
public IAnimationStateMachine getAsm() {
return asm;
}
public float getAnimationOffsetValue() {
return animationOffsetValue;
}
public void setAnimationOffsetValue(float animationOffsetValue) {
this.animationOffsetValue = animationOffsetValue;
}
public VariableValue getAnimationOffset() {
return animationOffset;
}
public VariableValue getCycleLength() {
return cycleLength;
}
public EnumDemonWillType getType() {
return type;
}
public void setType(EnumDemonWillType type) {
this.type = type;
}
public double getCurrentInversion() {
return currentInversion;
}
public void setCurrentInversion(double currentInversion) {
this.currentInversion = currentInversion;
}
public int getConsecutiveFailedChecks() {
return consecutiveFailedChecks;
}
public void setConsecutiveFailedChecks(int consecutiveFailedChecks) {
this.consecutiveFailedChecks = consecutiveFailedChecks;
}
public int getConsecutiveFailedAirChecks() {
return consecutiveFailedAirChecks;
}
public void setConsecutiveFailedAirChecks(int consecutiveFailedAirChecks) {
this.consecutiveFailedAirChecks = consecutiveFailedAirChecks;
}
public int getCurrentInfectionRadius() {
return currentInfectionRadius;
}
public void setCurrentInfectionRadius(int currentInfectionRadius) {
this.currentInfectionRadius = currentInfectionRadius;
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public boolean isRegistered() {
return isRegistered;
}
public void setRegistered(boolean registered) {
isRegistered = registered;
}
public static BlockPos findCandidatePositionForPillar(World world, EnumDemonWillType type, BlockPos pos, List<BlockPos> posList, double tooCloseDistance, double wantedAverageDistance) {
int maxIterations = 100;
int heightCheckRange = 3;
for (int i = 0; i < maxIterations; i++) {
Collections.shuffle(posList);
BlockPos pillarPos = posList.get(0);
Vec3d vec = new Vec3d(world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1, world.rand.nextDouble() * 2 - 1).normalize().scale(wantedAverageDistance);
BlockPos centralPos = pillarPos.add(vec.x, vec.y, vec.z);
BlockPos testPos = null;
candidateTest:
for (int h = 0; h <= heightCheckRange; h++) {
for (int sig = -1; sig <= 1; sig += (h > 0 ? 2 : 3)) {
BlockPos candidatePos = centralPos.add(0, sig * h, 0);
if (world.isAirBlock(candidatePos) && world.isAirBlock(candidatePos.up()) && world.isAirBlock(candidatePos.down()) && !world.isAirBlock(candidatePos.down(2))) {
testPos = candidatePos;
break candidateTest;
}
}
}
if (testPos != null) {
boolean isValid = true;
for (BlockPos pillarTestPos : posList) {
if (pillarTestPos.distanceSq(testPos) <= tooCloseDistance * tooCloseDistance) {
isValid = false;
break;
}
}
if (isValid) {
return testPos;
}
}
}
return BlockPos.ORIGIN;
}
public static double getWillPerOperation() {
return willPerOperation;
}
public static void setWillPerOperation(double willPerOperation) {
TileInversionPillar.willPerOperation = willPerOperation;
}
public static double getInversionPerOperation() {
return inversionPerOperation;
}
public static void setInversionPerOperation(double inversionPerOperation) {
TileInversionPillar.inversionPerOperation = inversionPerOperation;
}
public static double getAddedInversionPerFailedCheck() {
return addedInversionPerFailedCheck;
}
public static void setAddedInversionPerFailedCheck(double addedInversionPerFailedCheck) {
TileInversionPillar.addedInversionPerFailedCheck = addedInversionPerFailedCheck;
}
public static double getInversionToIncreaseRadius() {
return inversionToIncreaseRadius;
}
public static void setInversionToIncreaseRadius(double inversionToIncreaseRadius) {
TileInversionPillar.inversionToIncreaseRadius = inversionToIncreaseRadius;
}
public static double getInversionToAddPillar() {
return inversionToAddPillar;
}
public static void setInversionToAddPillar(double inversionToAddPillar) {
TileInversionPillar.inversionToAddPillar = inversionToAddPillar;
}
public static double getOperationThreshold() {
return operationThreshold;
}
public static void setOperationThreshold(double operationThreshold) {
TileInversionPillar.operationThreshold = operationThreshold;
}
public static double getInversionToSpreadWill() {
return inversionToSpreadWill;
}
public static void setInversionToSpreadWill(double inversionToSpreadWill) {
TileInversionPillar.inversionToSpreadWill = inversionToSpreadWill;
}
public static double getWillPushRate() {
return willPushRate;
}
public static void setWillPushRate(double willPushRate) {
TileInversionPillar.willPushRate = willPushRate;
}
public static double getInversionCostPerWillSpread() {
return inversionCostPerWillSpread;
}
public static void setInversionCostPerWillSpread(double inversionCostPerWillSpread) {
TileInversionPillar.inversionCostPerWillSpread = inversionCostPerWillSpread;
}
public static double getMinimumWillForChunkWhenSpreading() {
return minimumWillForChunkWhenSpreading;
}
public static void setMinimumWillForChunkWhenSpreading(double minimumWillForChunkWhenSpreading) {
TileInversionPillar.minimumWillForChunkWhenSpreading = minimumWillForChunkWhenSpreading;
}
public static double getMaxWillForChunk() {
return maxWillForChunk;
}
}

View file

@ -1,459 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.BloodMagic;
import WayofTime.bloodmagic.core.RegistrarBloodMagicItems;
import WayofTime.bloodmagic.core.data.Binding;
import WayofTime.bloodmagic.core.data.SoulNetwork;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.event.RitualEvent;
import WayofTime.bloodmagic.iface.IBindable;
import WayofTime.bloodmagic.item.ItemActivationCrystal;
import WayofTime.bloodmagic.ritual.AreaDescriptor;
import WayofTime.bloodmagic.ritual.EnumReaderBoundaries;
import WayofTime.bloodmagic.ritual.IMasterRitualStone;
import WayofTime.bloodmagic.ritual.Ritual;
import WayofTime.bloodmagic.soul.DemonWillHolder;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.tile.base.TileTicking;
import WayofTime.bloodmagic.util.ChatUtil;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.util.helper.*;
import com.google.common.base.Strings;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import javax.annotation.Nullable;
import java.util.*;
public class TileMasterRitualStone extends TileTicking implements IMasterRitualStone {
protected final Map<String, AreaDescriptor> modableRangeMap = new HashMap<>();
private UUID owner;
private SoulNetwork cachedNetwork;
private boolean active;
private boolean redstoned;
private int activeTime;
private int cooldown;
private Ritual currentRitual;
private Direction direction = Direction.NORTH;
private boolean inverted;
private List<EnumDemonWillType> currentActiveWillConfig = new ArrayList<>();
@Override
public void onUpdate() {
if (getWorld().isRemote)
return;
if (isPowered() && isActive()) {
active = false;
redstoned = true;
stopRitual(Ritual.BreakType.REDSTONE);
return;
}
if (!isActive() && !isPowered() && isRedstoned() && getCurrentRitual() != null) {
active = true;
ItemStack crystalStack = NBTHelper.checkNBT(new ItemStack(RegistrarBloodMagicItems.ACTIVATION_CRYSTAL, 1, getCurrentRitual().getCrystalLevel()));
BindableHelper.applyBinding(crystalStack, new Binding(owner, PlayerHelper.getUsernameFromUUID(owner)));
activateRitual(crystalStack, null, getCurrentRitual());
redstoned = false;
}
if (getCurrentRitual() != null && isActive()) {
if (activeTime % getCurrentRitual().getRefreshTime() == 0)
performRitual(getWorld(), getPos());
activeTime++;
}
}
@Override
public void deserialize(CompoundNBT tag) {
owner = tag.hasUniqueId("owner") ? tag.getUniqueId("owner") : null;
if (owner != null)
cachedNetwork = NetworkHelper.getSoulNetwork(owner);
currentRitual = BloodMagic.RITUAL_MANAGER.getRitual(tag.getString(Constants.NBT.CURRENT_RITUAL));
if (currentRitual != null) {
CompoundNBT ritualTag = tag.getCompound(Constants.NBT.CURRENT_RITUAL_TAG);
if (!ritualTag.isEmpty()) {
currentRitual.readFromNBT(ritualTag);
}
}
active = tag.getBoolean(Constants.NBT.IS_RUNNING);
activeTime = tag.getInt(Constants.NBT.RUNTIME);
direction = Direction.VALUES[tag.getInt(Constants.NBT.DIRECTION)];
redstoned = tag.getBoolean(Constants.NBT.IS_REDSTONED);
for (EnumDemonWillType type : EnumDemonWillType.values()) {
if (tag.getBoolean("EnumWill" + type)) {
currentActiveWillConfig.add(type);
}
}
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
String ritualId = BloodMagic.RITUAL_MANAGER.getId(getCurrentRitual());
if (owner != null)
tag.putUniqueId("owner", owner);
tag.putString(Constants.NBT.CURRENT_RITUAL, Strings.isNullOrEmpty(ritualId) ? "" : ritualId);
if (currentRitual != null) {
CompoundNBT ritualTag = new CompoundNBT();
currentRitual.writeToNBT(ritualTag);
tag.put(Constants.NBT.CURRENT_RITUAL_TAG, ritualTag);
}
tag.putBoolean(Constants.NBT.IS_RUNNING, isActive());
tag.putInt(Constants.NBT.RUNTIME, getActiveTime());
tag.putInt(Constants.NBT.DIRECTION, direction.getIndex());
tag.putBoolean(Constants.NBT.IS_REDSTONED, redstoned);
for (EnumDemonWillType type : currentActiveWillConfig) {
tag.putBoolean("EnumWill" + type, true);
}
return tag;
}
@Override
public boolean activateRitual(ItemStack activationCrystal, @Nullable PlayerEntity activator, Ritual ritual) {
if (PlayerHelper.isFakePlayer(activator))
return false;
Binding binding = ((IBindable) activationCrystal.getItem()).getBinding(activationCrystal);
if (binding != null && ritual != null) {
if (activationCrystal.getItem() instanceof ItemActivationCrystal) {
int crystalLevel = ((ItemActivationCrystal) activationCrystal.getItem()).getCrystalLevel(activationCrystal);
if (RitualHelper.canCrystalActivate(ritual, crystalLevel)) {
if (!getWorld().isRemote) {
SoulNetwork network = NetworkHelper.getSoulNetwork(binding);
if (!isRedstoned() && network.getCurrentEssence() < ritual.getActivationCost() && (activator != null && !activator.capabilities.isCreativeMode)) {
activator.sendStatusMessage(new TranslationTextComponent("chat.bloodmagic.ritual.weak"), true);
return false;
}
if (currentRitual != null)
currentRitual.stopRitual(this, Ritual.BreakType.ACTIVATE);
RitualEvent.RitualActivatedEvent event = new RitualEvent.RitualActivatedEvent(this, binding.getOwnerId(), ritual, activator, activationCrystal, crystalLevel);
if (MinecraftForge.EVENT_BUS.post(event)) {
if (activator != null)
activator.sendStatusMessage(new TranslationTextComponent("chat.bloodmagic.ritual.prevent"), true);
return false;
}
if (ritual.activateRitual(this, activator, binding.getOwnerId())) {
if (!isRedstoned() && (activator != null && !activator.capabilities.isCreativeMode))
network.syphon(ticket(ritual.getActivationCost()));
if (activator != null)
activator.sendStatusMessage(new TranslationTextComponent("chat.bloodmagic.ritual.activate"), true);
this.active = true;
this.owner = binding.getOwnerId();
this.cachedNetwork = network;
this.currentRitual = ritual;
if (!checkBlockRanges(ritual.getModableRangeMap()))
addBlockRanges(ritual.getModableRangeMap());
notifyUpdate();
return true;
}
}
notifyUpdate();
return true;
}
}
} else {
if (activator != null)
activator.sendStatusMessage(new TranslationTextComponent("chat.bloodmagic.ritual.notValid"), true);
}
return false;
}
@Override
public void performRitual(World world, BlockPos pos) {
if (!world.isRemote && getCurrentRitual() != null && BloodMagic.RITUAL_MANAGER.enabled(BloodMagic.RITUAL_MANAGER.getId(currentRitual), false)) {
if (RitualHelper.checkValidRitual(getWorld(), getPos(), currentRitual, getDirection())) {
Ritual ritual = getCurrentRitual();
RitualEvent.RitualRunEvent event = new RitualEvent.RitualRunEvent(this, getOwner(), ritual);
if (MinecraftForge.EVENT_BUS.post(event))
return;
if (!checkBlockRanges(getCurrentRitual().getModableRangeMap()))
addBlockRanges(getCurrentRitual().getModableRangeMap());
getCurrentRitual().performRitual(this);
} else {
stopRitual(Ritual.BreakType.BREAK_STONE);
}
}
}
@Override
public void stopRitual(Ritual.BreakType breakType) {
if (!getWorld().isRemote && getCurrentRitual() != null) {
RitualEvent.RitualStopEvent event = new RitualEvent.RitualStopEvent(this, getOwner(), getCurrentRitual(), breakType);
if (MinecraftForge.EVENT_BUS.post(event))
return;
getCurrentRitual().stopRitual(this, breakType);
if (breakType != Ritual.BreakType.REDSTONE) {
this.currentRitual = null;
this.active = false;
this.activeTime = 0;
}
notifyUpdate();
}
}
@Override
public int getCooldown() {
return cooldown;
}
@Override
public void setCooldown(int cooldown) {
this.cooldown = cooldown;
}
@Override
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
@Override
public boolean areTanksEmpty() {
return false;
}
@Override
public int getRunningTime() {
return activeTime;
}
@Override
public UUID getOwner() {
return owner;
}
public void setOwner(UUID owner) {
this.owner = owner;
}
@Override
public SoulNetwork getOwnerNetwork() {
return cachedNetwork;
}
@Override
public World getWorld() {
return super.getWorld();
}
@Override
public BlockPos getPos() {
return super.getPos();
}
@Override
public World getWorldObj() {
return getWorld();
}
@Override
public BlockPos getBlockPos() {
return getPos();
}
@Override
public String getNextBlockRange(String range) {
if (this.currentRitual != null) {
return this.currentRitual.getNextBlockRange(range);
}
return "";
}
@Override
public void provideInformationOfRitualToPlayer(PlayerEntity player) {
if (this.currentRitual != null) {
ChatUtil.sendNoSpam(player, this.currentRitual.provideInformationOfRitualToPlayer(player));
}
}
@Override
public void provideInformationOfRangeToPlayer(PlayerEntity player, String range) {
if (this.currentRitual != null && this.currentRitual.getListOfRanges().contains(range)) {
ChatUtil.sendNoSpam(player, this.currentRitual.provideInformationOfRangeToPlayer(player, range));
}
}
@Override
public void setActiveWillConfig(PlayerEntity player, List<EnumDemonWillType> typeList) {
this.currentActiveWillConfig = typeList;
}
@Override
public EnumReaderBoundaries setBlockRangeByBounds(PlayerEntity player, String range, BlockPos offset1, BlockPos offset2) {
AreaDescriptor descriptor = this.getBlockRange(range);
DemonWillHolder holder = WorldDemonWillHandler.getWillHolder(world, getBlockPos());
EnumReaderBoundaries modificationType = currentRitual.canBlockRangeBeModified(range, descriptor, this, offset1, offset2, holder);
if (modificationType == EnumReaderBoundaries.SUCCESS)
descriptor.modifyAreaByBlockPositions(offset1, offset2);
return modificationType;
}
@Override
public List<EnumDemonWillType> getActiveWillConfig() {
return new ArrayList<>(currentActiveWillConfig);
}
@Override
public void provideInformationOfWillConfigToPlayer(PlayerEntity player, List<EnumDemonWillType> typeList) {
//There is probably an easier way to make expanded chat messages
if (typeList.size() >= 1) {
Object[] translations = new TranslationTextComponent[typeList.size()];
StringBuilder constructedString = new StringBuilder("%s");
for (int i = 1; i < typeList.size(); i++) {
constructedString.append(", %s");
}
for (int i = 0; i < typeList.size(); i++) {
translations[i] = new TranslationTextComponent("tooltip.bloodmagic.currentBaseType." + typeList.get(i).name.toLowerCase());
}
ChatUtil.sendNoSpam(player, new TranslationTextComponent("ritual.bloodmagic.willConfig.set", new TranslationTextComponent(constructedString.toString(), translations)));
} else {
ChatUtil.sendNoSpam(player, new TranslationTextComponent("ritual.bloodmagic.willConfig.void"));
}
}
public boolean isPowered() {
if (inverted)
return !getWorld().isBlockPowered(getPos());
return getWorld().isBlockPowered(getPos());
}
public SoulNetwork getCachedNetwork() {
return cachedNetwork;
}
public void setCachedNetwork(SoulNetwork cachedNetwork) {
this.cachedNetwork = cachedNetwork;
}
public boolean isActive() {
return active;
}
@Override
public void setActive(boolean active) {
this.active = active;
}
public boolean isRedstoned() {
return redstoned;
}
public void setRedstoned(boolean redstoned) {
this.redstoned = redstoned;
}
public int getActiveTime() {
return activeTime;
}
public void setActiveTime(int activeTime) {
this.activeTime = activeTime;
}
public Ritual getCurrentRitual() {
return currentRitual;
}
public void setCurrentRitual(Ritual currentRitual) {
this.currentRitual = currentRitual;
}
public boolean isInverted() {
return inverted;
}
public void setInverted(boolean inverted) {
this.inverted = inverted;
}
public List<EnumDemonWillType> getCurrentActiveWillConfig() {
return currentActiveWillConfig;
}
public void setCurrentActiveWillConfig(List<EnumDemonWillType> currentActiveWillConfig) {
this.currentActiveWillConfig = currentActiveWillConfig;
}
/**
* Used to grab the range of a ritual for a given effect.
*
* @param range - Range that needs to be pulled.
* @return -
*/
public AreaDescriptor getBlockRange(String range) {
if (modableRangeMap.containsKey(range)) {
return modableRangeMap.get(range);
}
return null;
}
@Override
public void addBlockRange(String range, AreaDescriptor defaultRange) {
modableRangeMap.putIfAbsent(range, defaultRange.copy());
}
@Override
public void addBlockRanges(Map<String, AreaDescriptor> blockRanges) {
for (Map.Entry<String, AreaDescriptor> entry : blockRanges.entrySet()) {
modableRangeMap.putIfAbsent(entry.getKey(), entry.getValue().copy());
}
}
@Override
public void setBlockRange(String range, AreaDescriptor defaultRange) {
modableRangeMap.put(range, defaultRange.copy());
}
@Override
public void setBlockRanges(Map<String, AreaDescriptor> blockRanges) {
for (Map.Entry<String, AreaDescriptor> entry : blockRanges.entrySet()) {
modableRangeMap.put(entry.getKey(), entry.getValue().copy());
}
}
public boolean checkBlockRanges(Map<String, AreaDescriptor> blockRanges) {
for (Map.Entry<String, AreaDescriptor> entry : blockRanges.entrySet()) {
if (modableRangeMap.get(entry.getKey()) == null)
return false;
}
return true;
}
}

View file

@ -1,369 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.block.BlockMimic;
import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks;
import WayofTime.bloodmagic.core.RegistrarBloodMagicItems;
import WayofTime.bloodmagic.entity.mob.EntityMimic;
import WayofTime.bloodmagic.util.ChatUtil;
import WayofTime.bloodmagic.util.Utils;
import WayofTime.bloodmagic.util.StateUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PotionEntity;
import net.minecraft.block.Blocks;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.PotionUtils;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.Difficulty;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.List;
public class TileMimic extends TileInventory implements ITickable {
private static Field _blockMetadata = ReflectionHelper.findField(TileEntity.class, "blockMetadata", "field_145847_g");
public boolean dropItemsOnBreak = true;
public CompoundNBT tileTag = new CompoundNBT();
public TileEntity mimicedTile = null;
BlockState stateOfReplacedBlock = Blocks.AIR.getDefaultState();
public int playerCheckRadius = 5;
public int potionSpawnRadius = 5;
public int potionSpawnInterval = 40;
private int internalCounter = 0;
public TileMimic() {
super(2, "mimic");
}
@Override
public void update() {
if (getWorld().isRemote) {
return;
}
internalCounter++;
if (internalCounter % potionSpawnInterval == 0 && this.getBlockMetadata() == BlockMimic.sentientMimicMeta) {
ItemStack potionStack = this.getStackInSlot(1);
if (!potionStack.isEmpty()) {
AxisAlignedBB bb = new AxisAlignedBB(this.getPos()).expand(playerCheckRadius, playerCheckRadius, playerCheckRadius);
List<PlayerEntity> playerList = getWorld().getEntitiesWithinAABB(PlayerEntity.class, bb);
for (PlayerEntity player : playerList) {
if (!player.capabilities.isCreativeMode) {
double posX = this.pos.getX() + 0.5 + (2 * getWorld().rand.nextDouble() - 1) * potionSpawnRadius;
double posY = this.pos.getY() + 0.5 + (2 * getWorld().rand.nextDouble() - 1) * potionSpawnRadius;
double posZ = this.pos.getZ() + 0.5 + (2 * getWorld().rand.nextDouble() - 1) * potionSpawnRadius;
ItemStack newStack = new ItemStack(potionStack.getItem() == RegistrarBloodMagicItems.POTION_FLASK ? Items.SPLASH_POTION : potionStack.getItem());
newStack.setTagCompound(potionStack.getTagCompound());
PotionEntity potionEntity = new PotionEntity(getWorld(), posX, posY, posZ, newStack);
getWorld().spawnEntity(potionEntity);
break;
}
}
}
}
if (this.getBlockMetadata() == BlockMimic.sentientMimicMeta && getWorld().getDifficulty() != Difficulty.PEACEFUL && !(mimicedTile instanceof IInventory)) {
AxisAlignedBB bb = new AxisAlignedBB(this.getPos()).expand(playerCheckRadius, playerCheckRadius, playerCheckRadius);
List<PlayerEntity> playerList = getWorld().getEntitiesWithinAABB(PlayerEntity.class, bb);
for (PlayerEntity player : playerList) {
if (!player.capabilities.isCreativeMode && Utils.canEntitySeeBlock(getWorld(), player, getPos())) {
spawnMimicEntity(player);
break;
}
}
}
}
public boolean onBlockActivated(World world, BlockPos pos, BlockState state, PlayerEntity player, Hand hand, ItemStack heldItem, Direction side) {
if (!heldItem.isEmpty() && player.capabilities.isCreativeMode) {
List<EffectInstance> list = PotionUtils.getEffectsFromStack(heldItem);
if (!list.isEmpty()) {
if (!world.isRemote) {
setInventorySlotContents(1, heldItem.copy());
world.notifyBlockUpdate(pos, state, state, 3);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSet"));
}
return true;
} else if (heldItem.getItem() == RegistrarBloodMagicItems.POTION_FLASK) {
//The potion flask is empty, therefore we have to reset the stored potion.
if (!world.isRemote) {
setInventorySlotContents(1, ItemStack.EMPTY);
world.notifyBlockUpdate(pos, state, state, 3);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionRemove"));
}
return true;
}
}
if (performSpecialAbility(player, side)) {
return true;
}
if (player.isSneaking())
return false;
if (!player.getHeldItem(hand).isEmpty() && player.getHeldItem(hand).getItem() == new ItemStack(RegistrarBloodMagicBlocks.MIMIC).getItem())
return false;
if (!getStackInSlot(0).isEmpty() && !player.getHeldItem(hand).isEmpty())
return false;
if (!dropItemsOnBreak && !player.capabilities.isCreativeMode)
return false;
Utils.insertItemToTile(this, player, 0);
ItemStack stack = getStackInSlot(0);
if (stateOfReplacedBlock == Blocks.AIR.getDefaultState()) {
if (!stack.isEmpty() && stack.getItem() instanceof BlockItem) {
Block block = ((BlockItem) stack.getItem()).getBlock();
stateOfReplacedBlock = block.getDefaultState();
}
}
this.refreshTileEntity();
if (player.capabilities.isCreativeMode) {
dropItemsOnBreak = getStackInSlot(0).isEmpty();
}
world.notifyBlockUpdate(pos, state, state, 3);
return true;
}
public boolean performSpecialAbility(PlayerEntity player, Direction sideHit) {
switch (this.getBlockMetadata()) {
case BlockMimic.sentientMimicMeta:
if (player.capabilities.isCreativeMode) {
if (player.isSneaking()) {
playerCheckRadius = Math.max(playerCheckRadius - 1, 0);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.down", playerCheckRadius));
} else {
playerCheckRadius++;
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.up", playerCheckRadius));
}
return false;
}
return spawnMimicEntity(player);
default:
if (!player.capabilities.isCreativeMode) {
return false;
}
if (player.getActiveItemStack().isEmpty() && !getStackInSlot(1).isEmpty()) {
switch (sideHit) {
case EAST: //When the block is clicked on the EAST or WEST side, potionSpawnRadius is edited.
case WEST:
if (player.isSneaking()) {
potionSpawnRadius = Math.max(potionSpawnRadius - 1, 0);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSpawnRadius.down", potionSpawnRadius));
} else {
potionSpawnRadius++;
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionSpawnRadius.up", potionSpawnRadius));
}
break;
case NORTH: //When the block is clicked on the NORTH or SOUTH side, detectRadius is edited.
case SOUTH:
if (player.isSneaking()) {
playerCheckRadius = Math.max(playerCheckRadius - 1, 0);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.down", playerCheckRadius));
} else {
playerCheckRadius++;
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.detectRadius.up", playerCheckRadius));
}
break;
case UP: //When the block is clicked on the UP or DOWN side, potionSpawnInterval is edited.
case DOWN:
if (player.isSneaking()) {
potionSpawnInterval = Math.max(potionSpawnInterval - 1, 1);
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionInterval.down", potionSpawnInterval));
} else {
potionSpawnInterval++;
ChatUtil.sendNoSpam(player, new TranslationTextComponent("chat.bloodmagic.mimic.potionInterval.up", potionSpawnInterval));
}
break;
default:
break;
}
return true;
}
}
return false;
}
public boolean spawnMimicEntity(PlayerEntity target) {
if (this.getWorld().getDifficulty() == Difficulty.PEACEFUL) {
return false;
}
if (this.getStackInSlot(0).isEmpty() || getWorld().isRemote) {
return false;
}
EntityMimic mimicEntity = new EntityMimic(getWorld());
mimicEntity.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
mimicEntity.initializeMimic(getStackInSlot(0), tileTag, dropItemsOnBreak, stateOfReplacedBlock, playerCheckRadius, pos);
tileTag = null;
mimicedTile = null;
this.setInventorySlotContents(0, ItemStack.EMPTY);
getWorld().spawnEntity(mimicEntity);
if (target != null) {
mimicEntity.setAttackTarget(target);
}
getWorld().setBlockToAir(pos);
return true;
}
public void refreshTileEntity() {
if (mimicedTile != null) {
dropMimicedTileInventory();
}
mimicedTile = getTileFromStackWithTag(getWorld(), pos, getStackInSlot(0), tileTag, stateOfReplacedBlock);
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
dropItemsOnBreak = tag.getBoolean("dropItemsOnBreak");
tileTag = tag.getCompound("tileTag");
stateOfReplacedBlock = StateUtil.parseState(tag.getString("stateOfReplacedBlock"));
mimicedTile = getTileFromStackWithTag(getWorld(), pos, getStackInSlot(0), tileTag, stateOfReplacedBlock);
playerCheckRadius = tag.getInt("playerCheckRadius");
potionSpawnRadius = tag.getInt("potionSpawnRadius");
potionSpawnInterval = Math.max(1, tag.getInt("potionSpawnInterval"));
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putBoolean("dropItemsOnBreak", dropItemsOnBreak);
tag.put("tileTag", tileTag);
tag.putInt("playerCheckRadius", playerCheckRadius);
tag.putInt("potionSpawnRadius", potionSpawnRadius);
tag.putInt("potionSpawnInterval", potionSpawnInterval);
tag.putString("stateOfReplacedBlock", stateOfReplacedBlock.toString());
return tag;
}
@Override
public void dropItems() {
if (dropItemsOnBreak) {
InventoryHelper.dropInventoryItems(getWorld(), getPos(), this);
}
dropMimicedTileInventory();
}
public void dropMimicedTileInventory() {
if (!getWorld().isRemote && mimicedTile instanceof IInventory) {
InventoryHelper.dropInventoryItems(getWorld(), getPos(), (IInventory) mimicedTile);
}
}
public BlockState getReplacedState() {
return stateOfReplacedBlock;
}
public void setReplacedState(BlockState state) {
stateOfReplacedBlock = state;
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack) {
return slot == 0 && dropItemsOnBreak;
}
public static void replaceMimicWithBlockActual(TileMimic mimic) {
World world = mimic.getWorld();
BlockPos pos = mimic.getPos();
replaceMimicWithBlockActual(world, pos, mimic.getStackInSlot(0), mimic.tileTag, mimic.stateOfReplacedBlock);
}
public static boolean replaceMimicWithBlockActual(World world, BlockPos pos, ItemStack stack, CompoundNBT tileTag, BlockState replacementState) {
if (!stack.isEmpty() && stack.getItem() instanceof BlockItem) {
Block block = ((BlockItem) stack.getItem()).getBlock();
BlockState state = replacementState;
if (world.setBlockState(pos, state, 3)) {
TileEntity tile = world.getTileEntity(pos);
if (tile != null) {
tileTag.putInt("x", pos.getX());
tileTag.putInt("y", pos.getY());
tileTag.putInt("z", pos.getZ());
tile.readFromNBT(tileTag);
}
return true;
}
}
return false;
}
@Nullable
public static TileEntity getTileFromStackWithTag(World world, BlockPos pos, ItemStack stack, @Nullable CompoundNBT tag, BlockState replacementState) {
if (!stack.isEmpty() && stack.getItem() instanceof BlockItem) {
Block block = ((BlockItem) stack.getItem()).getBlock();
BlockState state = replacementState;
if (block.hasTileEntity(state)) {
TileEntity tile = block.createTileEntity(world, state);
if (tile == null)
return null;
if (tag != null) {
CompoundNBT copyTag = tag.copy();
copyTag.putInt("x", pos.getX());
copyTag.putInt("y", pos.getY());
copyTag.putInt("z", pos.getZ());
tile.readFromNBT(copyTag);
}
tile.setWorld(world);
try {
_blockMetadata.setInt(tile, block.getMetaFromState(replacementState));
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
return tile;
}
}
return null;
}
}

View file

@ -1,46 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.item.sigil.ItemSigilPhantomBridge;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.tile.base.TileTicking;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
public class TilePhantomBlock extends TileTicking {
private int ticksRemaining = 10;
public TilePhantomBlock() {
}
public TilePhantomBlock(int ticksRemaining) {
this.ticksRemaining = ticksRemaining;
}
@Override
public void deserialize(CompoundNBT tagCompound) {
this.ticksRemaining = tagCompound.getInt(Constants.NBT.TICKS_REMAINING);
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
tagCompound.putInt(Constants.NBT.TICKS_REMAINING, ticksRemaining);
return tagCompound;
}
@Override
public void onUpdate() {
if (!world.isRemote) {
PlayerEntity player = world.getClosestPlayer(getPos().getX(), getPos().getY(), getPos().getZ(), 10.0D, ItemSigilPhantomBridge.IS_PHANTOM_ACTIVE);
if (player != null && !player.isSneaking())
return;
ticksRemaining--;
}
if (ticksRemaining <= 0) {
world.setBlockToAir(getPos());
world.removeTileEntity(getPos());
}
}
}

View file

@ -1,83 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.iface.IPurificationAsh;
import WayofTime.bloodmagic.ritual.AreaDescriptor;
import WayofTime.bloodmagic.util.helper.PurificationHelper;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ServerWorld;
import java.util.List;
public class TilePurificationAltar extends TileInventory implements ITickable {
public AreaDescriptor purityArea = new AreaDescriptor.Rectangle(new BlockPos(-5, -5, -5), 11);
public double totalPurity = 0;
public double maxPurity = 0;
public double purityRate = 0;
public TilePurificationAltar() {
super(1, "purificationAltar");
}
@Override
public void update() {
if (totalPurity <= 0) {
ItemStack stack = this.getStackInSlot(0);
if (!stack.isEmpty() && stack.getItem() instanceof IPurificationAsh) {
totalPurity = ((IPurificationAsh) stack.getItem()).getTotalPurity(stack);
maxPurity = ((IPurificationAsh) stack.getItem()).getMaxPurity(stack);
purityRate = ((IPurificationAsh) stack.getItem()).getPurityRate(stack);
}
} else {
return;
}
AxisAlignedBB aabb = purityArea.getAABB(getPos());
List<AnimalEntity> animalList = getWorld().getEntitiesWithinAABB(AnimalEntity.class, aabb);
if (animalList.isEmpty()) {
return;
}
boolean hasPerformed = false;
for (AnimalEntity animal : animalList) {
double added = PurificationHelper.addPurity(animal, Math.min(purityRate, totalPurity), maxPurity);
if (added > 0) {
totalPurity -= purityRate;
hasPerformed = true;
}
}
if (hasPerformed) {
if (getWorld().rand.nextInt(4) == 0 && getWorld() instanceof ServerWorld) {
ServerWorld server = (ServerWorld) getWorld();
server.spawnParticle(EnumParticleTypes.FLAME, pos.getX() + 0.5, pos.getY() + 1.2, pos.getZ() + 0.5, 1, 0.02, 0.03, 0.02, 0);
}
}
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
totalPurity = tag.getDouble("totalPurity");
maxPurity = tag.getDouble("maxPurity");
purityRate = tag.getDouble("purityRate");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putDouble("totalPurity", totalPurity);
tag.putDouble("maxPurity", maxPurity);
tag.putDouble("purityRate", purityRate);
return tag;
}
}

View file

@ -1,284 +1,421 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.api.event.BloodMagicCraftedEvent;
import WayofTime.bloodmagic.api.impl.BloodMagicAPI;
import WayofTime.bloodmagic.api.impl.recipe.RecipeTartaricForge;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.soul.IDemonWill;
import WayofTime.bloodmagic.soul.IDemonWillConduit;
import WayofTime.bloodmagic.soul.IDemonWillGem;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ITickable;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.items.ItemHandlerHelper;
package wayoftime.bloodmagic.tile;
import java.util.ArrayList;
import java.util.List;
public class TileSoulForge extends TileInventory implements ITickable, IDemonWillConduit {
public static final int ticksRequired = 100;
public static final double worldWillTransferRate = 1;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.IIntArray;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.registries.ObjectHolder;
import wayoftime.bloodmagic.api.event.BloodMagicCraftedEvent;
import wayoftime.bloodmagic.api.impl.BloodMagicAPI;
import wayoftime.bloodmagic.api.impl.recipe.RecipeTartaricForge;
import wayoftime.bloodmagic.tile.contailer.ContainerSoulForge;
import wayoftime.bloodmagic.util.Constants;
import wayoftime.bloodmagic.will.EnumDemonWillType;
import wayoftime.bloodmagic.will.IDemonWill;
import wayoftime.bloodmagic.will.IDemonWillConduit;
import wayoftime.bloodmagic.will.IDemonWillGem;
public static final int soulSlot = 4;
public static final int outputSlot = 5;
public class TileSoulForge extends TileInventory
implements ITickableTileEntity, INamedContainerProvider, IDemonWillConduit
{
@ObjectHolder("bloodmagic:soulforge")
public static TileEntityType<TileSoulForge> TYPE;
//Input slots are from 0 to 3.
public static final int ticksRequired = 100;
public static final double worldWillTransferRate = 1;
public int burnTime = 0;
public static final int soulSlot = 4;
public static final int outputSlot = 5;
public TileSoulForge() {
super(6, "soulForge");
}
// Input slots are from 0 to 3.
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
public int burnTime = 0;
burnTime = tag.getInt(Constants.NBT.SOUL_FORGE_BURN);
}
public TileSoulForge(TileEntityType<?> type)
{
super(type, 6, "soulforge");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
public TileSoulForge()
{
this(TYPE);
}
tag.putInt(Constants.NBT.SOUL_FORGE_BURN, burnTime);
return tag;
}
@Override
public void deserialize(CompoundNBT tag)
{
super.deserialize(tag);
@Override
public void update() {
if (!getWorld().isRemote) {
for (EnumDemonWillType type : EnumDemonWillType.values()) {
double willInWorld = WorldDemonWillHandler.getCurrentWill(getWorld(), pos, type);
double filled = Math.min(willInWorld, worldWillTransferRate);
burnTime = tag.getInt(Constants.NBT.SOUL_FORGE_BURN);
}
if (filled > 0) {
filled = this.fillDemonWill(type, filled, false);
filled = WorldDemonWillHandler.drainWill(getWorld(), pos, type, filled, false);
@Override
public CompoundNBT serialize(CompoundNBT tag)
{
super.serialize(tag);
if (filled > 0) {
this.fillDemonWill(type, filled, true);
WorldDemonWillHandler.drainWill(getWorld(), pos, type, filled, true);
}
}
}
}
tag.putInt(Constants.NBT.SOUL_FORGE_BURN, burnTime);
return tag;
}
if (!hasSoulGemOrSoul()) {
burnTime = 0;
return;
}
public final IIntArray TileData = new IIntArray()
{
@Override
public int get(int index)
{
switch (index)
{
case 0:
return burnTime;
case 1:
return ticksRequired;
case 2:
return 0;
default:
throw new IllegalArgumentException("Invalid index: " + index);
}
}
double soulsInGem = getWill(EnumDemonWillType.DEFAULT);
@Override
public void set(int index, int value)
{
throw new IllegalStateException("Cannot set values through IIntArray");
}
List<ItemStack> inputList = new ArrayList<>();
@Override
public int size()
{
return 3;
}
};
for (int i = 0; i < 4; i++)
if (!getStackInSlot(i).isEmpty())
inputList.add(getStackInSlot(i));
@Override
public void tick()
{
if (!hasSoulGemOrSoul())
{
burnTime = 0;
return;
}
RecipeTartaricForge recipe = BloodMagicAPI.INSTANCE.getRecipeRegistrar().getTartaricForge(inputList);
if (recipe != null && (soulsInGem >= recipe.getMinimumSouls() || burnTime > 0)) {
if (canCraft(recipe)) {
burnTime++;
double soulsInGem = getWill(EnumDemonWillType.DEFAULT);
if (burnTime == ticksRequired) {
if (!getWorld().isRemote) {
double requiredSouls = recipe.getSoulDrain();
if (requiredSouls > 0) {
if (!getWorld().isRemote && soulsInGem >= recipe.getMinimumSouls()) {
consumeSouls(EnumDemonWillType.DEFAULT, requiredSouls);
}
}
List<ItemStack> inputList = new ArrayList<>();
if (!getWorld().isRemote && soulsInGem >= recipe.getMinimumSouls())
craftItem(recipe);
}
for (int i = 0; i < 4; i++) if (!getStackInSlot(i).isEmpty())
inputList.add(getStackInSlot(i));
burnTime = 0;
} else if (burnTime > ticksRequired + 10) {
burnTime = 0;
}
} else {
burnTime = 0;
}
} else {
burnTime = 0;
}
}
RecipeTartaricForge recipe = BloodMagicAPI.INSTANCE.getRecipeRegistrar().getTartaricForge(world, inputList);
if (recipe != null && (soulsInGem >= recipe.getMinimumSouls() || burnTime > 0))
{
if (canCraft(recipe))
{
burnTime++;
public double getProgressForGui() {
return ((double) burnTime) / ticksRequired;
}
if (burnTime == ticksRequired)
{
if (!getWorld().isRemote)
{
double requiredSouls = recipe.getSoulDrain();
if (requiredSouls > 0)
{
if (!getWorld().isRemote && soulsInGem >= recipe.getMinimumSouls())
{
consumeSouls(EnumDemonWillType.DEFAULT, requiredSouls);
}
}
private boolean canCraft(RecipeTartaricForge recipe) {
if (recipe == null)
return false;
if (!getWorld().isRemote && soulsInGem >= recipe.getMinimumSouls())
craftItem(recipe);
}
ItemStack currentOutputStack = getStackInSlot(outputSlot);
if (recipe.getOutput().isEmpty())
return false;
if (currentOutputStack.isEmpty())
return true;
if (!currentOutputStack.isItemEqual(recipe.getOutput()))
return false;
int result = currentOutputStack.getCount() + recipe.getOutput().getCount();
return result <= getInventoryStackLimit() && result <= currentOutputStack.getMaxStackSize();
burnTime = 0;
} else if (burnTime > ticksRequired + 10)
{
burnTime = 0;
}
} else
{
burnTime = 0;
}
} else
{
burnTime = 0;
}
}
}
private boolean canCraft(RecipeTartaricForge recipe)
{
if (recipe == null)
return false;
public void craftItem(RecipeTartaricForge recipe) {
if (this.canCraft(recipe)) {
ItemStack currentOutputStack = getStackInSlot(outputSlot);
ItemStack currentOutputStack = getStackInSlot(outputSlot);
if (recipe.getOutput().isEmpty())
return false;
if (currentOutputStack.isEmpty())
return true;
if (!currentOutputStack.isItemEqual(recipe.getOutput()))
return false;
int result = currentOutputStack.getCount() + recipe.getOutput().getCount();
return result <= getInventoryStackLimit() && result <= currentOutputStack.getMaxStackSize();
List<ItemStack> inputList = new ArrayList<>();
for (int i = 0; i < 4; i++)
if (!getStackInSlot(i).isEmpty())
inputList.add(getStackInSlot(i).copy());
}
BloodMagicCraftedEvent.SoulForge event = new BloodMagicCraftedEvent.SoulForge(recipe.getOutput().copy(), inputList.toArray(new ItemStack[0]));
MinecraftForge.EVENT_BUS.post(event);
public void craftItem(RecipeTartaricForge recipe)
{
if (this.canCraft(recipe))
{
ItemStack currentOutputStack = getStackInSlot(outputSlot);
if (currentOutputStack.isEmpty()) {
setInventorySlotContents(outputSlot, event.getOutput());
} else if (ItemHandlerHelper.canItemStacksStack(currentOutputStack, event.getOutput())) {
currentOutputStack.grow(event.getOutput().getCount());
}
List<ItemStack> inputList = new ArrayList<>();
for (int i = 0; i < 4; i++) if (!getStackInSlot(i).isEmpty())
inputList.add(getStackInSlot(i).copy());
consumeInventory();
}
}
BloodMagicCraftedEvent.SoulForge event = new BloodMagicCraftedEvent.SoulForge(recipe.getOutput().copy(), inputList.toArray(new ItemStack[0]));
MinecraftForge.EVENT_BUS.post(event);
public boolean hasSoulGemOrSoul() {
ItemStack soulStack = getStackInSlot(soulSlot);
if (currentOutputStack.isEmpty())
{
setInventorySlotContents(outputSlot, event.getOutput());
} else if (ItemHandlerHelper.canItemStacksStack(currentOutputStack, event.getOutput()))
{
currentOutputStack.grow(event.getOutput().getCount());
}
if (!soulStack.isEmpty()) {
if (soulStack.getItem() instanceof IDemonWill || soulStack.getItem() instanceof IDemonWillGem) {
return true;
}
}
consumeInventory();
}
}
return false;
}
@Override
public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_)
{
assert world != null;
return new ContainerSoulForge(this, TileData, p_createMenu_1_, p_createMenu_2_);
}
public double getWill(EnumDemonWillType type) {
ItemStack soulStack = getStackInSlot(soulSlot);
@Override
public ITextComponent getDisplayName()
{
return new StringTextComponent("Hellfire Forge");
}
if (soulStack != null) {
if (soulStack.getItem() instanceof IDemonWill && ((IDemonWill) soulStack.getItem()).getType(soulStack) == type) {
IDemonWill soul = (IDemonWill) soulStack.getItem();
return soul.getWill(type, soulStack);
}
public boolean hasSoulGemOrSoul()
{
ItemStack soulStack = getStackInSlot(soulSlot);
if (soulStack.getItem() instanceof IDemonWillGem) {
IDemonWillGem soul = (IDemonWillGem) soulStack.getItem();
return soul.getWill(type, soulStack);
}
}
if (!soulStack.isEmpty())
{
if (soulStack.getItem() instanceof IDemonWill || soulStack.getItem() instanceof IDemonWillGem)
{
return true;
}
}
return 0;
}
return false;
}
public double consumeSouls(EnumDemonWillType type, double requested) {
ItemStack soulStack = getStackInSlot(soulSlot);
public double getProgressForGui()
{
return ((double) burnTime) / ticksRequired;
}
if (soulStack != null) {
if (soulStack.getItem() instanceof IDemonWill && ((IDemonWill) soulStack.getItem()).getType(soulStack) == type) {
IDemonWill soul = (IDemonWill) soulStack.getItem();
double souls = soul.drainWill(type, soulStack, requested);
if (soul.getWill(type, soulStack) <= 0) {
setInventorySlotContents(soulSlot, ItemStack.EMPTY);
}
return souls;
}
// private boolean canCraft(RecipeTartaricForge recipe)
// {
// if (recipe == null)
// return false;
//
// ItemStack currentOutputStack = getStackInSlot(outputSlot);
// if (recipe.getOutput().isEmpty())
// return false;
// if (currentOutputStack.isEmpty())
// return true;
// if (!currentOutputStack.isItemEqual(recipe.getOutput()))
// return false;
// int result = currentOutputStack.getCount() + recipe.getOutput().getCount();
// return result <= getInventoryStackLimit() && result <= currentOutputStack.getMaxStackSize();
//
// }
//
// public void craftItem(RecipeTartaricForge recipe)
// {
// if (this.canCraft(recipe))
// {
// ItemStack currentOutputStack = getStackInSlot(outputSlot);
//
// List<ItemStack> inputList = new ArrayList<>();
// for (int i = 0; i < 4; i++) if (!getStackInSlot(i).isEmpty())
// inputList.add(getStackInSlot(i).copy());
//
// BloodMagicCraftedEvent.SoulForge event = new BloodMagicCraftedEvent.SoulForge(recipe.getOutput().copy(), inputList.toArray(new ItemStack[0]));
// MinecraftForge.EVENT_BUS.post(event);
//
// if (currentOutputStack.isEmpty())
// {
// setInventorySlotContents(outputSlot, event.getOutput());
// } else if (ItemHandlerHelper.canItemStacksStack(currentOutputStack, event.getOutput()))
// {
// currentOutputStack.grow(event.getOutput().getCount());
// }
//
// consumeInventory();
// }
// }
if (soulStack.getItem() instanceof IDemonWillGem) {
IDemonWillGem soul = (IDemonWillGem) soulStack.getItem();
return soul.drainWill(type, soulStack, requested, true);
}
}
public double getWill(EnumDemonWillType type)
{
ItemStack soulStack = getStackInSlot(soulSlot);
return 0;
}
if (soulStack != null)
{
if (soulStack.getItem() instanceof IDemonWill
&& ((IDemonWill) soulStack.getItem()).getType(soulStack) == type)
{
IDemonWill soul = (IDemonWill) soulStack.getItem();
return soul.getWill(type, soulStack);
}
public void consumeInventory() {
for (int i = 0; i < 4; i++) {
ItemStack inputStack = getStackInSlot(i);
if (!inputStack.isEmpty()) {
if (inputStack.getItem().hasContainerItem(inputStack)) {
setInventorySlotContents(i, inputStack.getItem().getContainerItem(inputStack));
continue;
}
if (soulStack.getItem() instanceof IDemonWillGem)
{
IDemonWillGem soul = (IDemonWillGem) soulStack.getItem();
return soul.getWill(type, soulStack);
}
}
inputStack.shrink(1);
if (inputStack.isEmpty()) {
setInventorySlotContents(i, ItemStack.EMPTY);
}
}
}
}
return 0;
}
@Override
public int getWeight() {
return 50;
}
public double consumeSouls(EnumDemonWillType type, double requested)
{
ItemStack soulStack = getStackInSlot(soulSlot);
@Override
public double fillDemonWill(EnumDemonWillType type, double amount, boolean doFill) {
if (amount <= 0) {
return 0;
}
if (soulStack != null)
{
if (soulStack.getItem() instanceof IDemonWill
&& ((IDemonWill) soulStack.getItem()).getType(soulStack) == type)
{
IDemonWill soul = (IDemonWill) soulStack.getItem();
double souls = soul.drainWill(type, soulStack, requested);
if (soul.getWill(type, soulStack) <= 0)
{
setInventorySlotContents(soulSlot, ItemStack.EMPTY);
}
return souls;
}
if (!canFill(type)) {
return 0;
}
if (soulStack.getItem() instanceof IDemonWillGem)
{
IDemonWillGem soul = (IDemonWillGem) soulStack.getItem();
return soul.drainWill(type, soulStack, requested, true);
}
}
ItemStack stack = this.getStackInSlot(soulSlot);
if (stack.isEmpty() || !(stack.getItem() instanceof IDemonWillGem)) {
return 0;
}
return 0;
}
IDemonWillGem willGem = (IDemonWillGem) stack.getItem();
return willGem.fillWill(type, stack, amount, doFill);
}
public void consumeInventory()
{
for (int i = 0; i < 4; i++)
{
ItemStack inputStack = getStackInSlot(i);
if (!inputStack.isEmpty())
{
if (inputStack.getItem().hasContainerItem(inputStack))
{
setInventorySlotContents(i, inputStack.getItem().getContainerItem(inputStack));
continue;
}
@Override
public double drainDemonWill(EnumDemonWillType type, double amount, boolean doDrain) {
ItemStack stack = this.getStackInSlot(soulSlot);
if (stack.isEmpty() || !(stack.getItem() instanceof IDemonWillGem)) {
return 0;
}
inputStack.shrink(1);
if (inputStack.isEmpty())
{
setInventorySlotContents(i, ItemStack.EMPTY);
}
}
}
}
IDemonWillGem willGem = (IDemonWillGem) stack.getItem();
@Override
public int getWeight()
{
return 50;
}
double drained = amount;
double current = willGem.getWill(type, stack);
if (current < drained) {
drained = current;
}
@Override
public double fillDemonWill(EnumDemonWillType type, double amount, boolean doFill)
{
if (amount <= 0)
{
return 0;
}
if (doDrain) {
drained = willGem.drainWill(type, stack, drained, true);
}
if (!canFill(type))
{
return 0;
}
return drained;
}
ItemStack stack = this.getStackInSlot(soulSlot);
if (stack.isEmpty() || !(stack.getItem() instanceof IDemonWillGem))
{
return 0;
}
@Override
public boolean canFill(EnumDemonWillType type) {
return true;
}
IDemonWillGem willGem = (IDemonWillGem) stack.getItem();
return willGem.fillWill(type, stack, amount, doFill);
}
@Override
public boolean canDrain(EnumDemonWillType type) {
return true;
}
@Override
public double drainDemonWill(EnumDemonWillType type, double amount, boolean doDrain)
{
ItemStack stack = this.getStackInSlot(soulSlot);
if (stack.isEmpty() || !(stack.getItem() instanceof IDemonWillGem))
{
return 0;
}
@Override
public double getCurrentWill(EnumDemonWillType type) {
return 0;
}
IDemonWillGem willGem = (IDemonWillGem) stack.getItem();
double drained = amount;
double current = willGem.getWill(type, stack);
if (current < drained)
{
drained = current;
}
if (doDrain)
{
drained = willGem.drainWill(type, stack, drained, true);
}
return drained;
}
@Override
public boolean canFill(EnumDemonWillType type)
{
return true;
}
@Override
public boolean canDrain(EnumDemonWillType type)
{
return true;
}
@Override
public double getCurrentWill(EnumDemonWillType type)
{
return 0;
}
}

View file

@ -1,84 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks;
import WayofTime.bloodmagic.tile.base.TileTicking;
import com.google.common.base.Strings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
public class TileSpectralBlock extends TileTicking {
private int ticksRemaining;
private String containedBlockName;
private int containedBlockMeta;
public TileSpectralBlock() {
}
@Override
public void deserialize(CompoundNBT tagCompound) {
ticksRemaining = tagCompound.getInt(Constants.NBT.TICKS_REMAINING);
containedBlockName = tagCompound.getString(Constants.NBT.CONTAINED_BLOCK_NAME);
containedBlockMeta = tagCompound.getInt(Constants.NBT.CONTAINED_BLOCK_META);
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
tagCompound.putInt(Constants.NBT.TICKS_REMAINING, ticksRemaining);
tagCompound.putString(Constants.NBT.CONTAINED_BLOCK_NAME, Strings.isNullOrEmpty(containedBlockName) ? "" : containedBlockName);
tagCompound.putInt(Constants.NBT.CONTAINED_BLOCK_META, containedBlockMeta);
return tagCompound;
}
@Override
public void onUpdate() {
if (getWorld().isRemote) {
return;
}
ticksRemaining--;
if (ticksRemaining <= 0) {
returnContainedBlock();
}
}
private void setContainedBlockInfo(BlockState blockState) {
containedBlockName = blockState.getBlock().getRegistryName().toString();
containedBlockMeta = blockState.getBlock().getMetaFromState(blockState);
}
private void setDuration(int duration) {
ticksRemaining = duration;
}
public void resetDuration(int reset) {
if (ticksRemaining < reset)
ticksRemaining = reset;
}
public void returnContainedBlock() {
Block block = null;
if (!Strings.isNullOrEmpty(containedBlockName))
block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(containedBlockName));
if (block != null && getWorld().setBlockState(pos, block.getStateFromMeta(containedBlockMeta)))
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
}
public static void createSpectralBlock(World world, BlockPos blockPos, int duration) {
if (world.isAirBlock(blockPos))
return;
BlockState cachedState = world.getBlockState(blockPos);
world.setBlockState(blockPos, RegistrarBloodMagicBlocks.SPECTRAL.getDefaultState());
TileSpectralBlock tile = (TileSpectralBlock) world.getTileEntity(blockPos);
tile.setContainedBlockInfo(cachedState);
tile.setDuration(duration);
}
}

View file

@ -1,149 +0,0 @@
package WayofTime.bloodmagic.tile;
import WayofTime.bloodmagic.block.BlockTeleposer;
import WayofTime.bloodmagic.command.sub.SubCommandTeleposer;
import WayofTime.bloodmagic.core.data.Binding;
import WayofTime.bloodmagic.core.data.SoulTicket;
import WayofTime.bloodmagic.event.TeleposeEvent;
import WayofTime.bloodmagic.item.ItemTelepositionFocus;
import WayofTime.bloodmagic.teleport.TeleportQueue;
import WayofTime.bloodmagic.teleport.Teleports;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.util.Utils;
import WayofTime.bloodmagic.util.helper.NetworkHelper;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import java.util.List;
import java.util.UUID;
public class TileTeleposer extends TileInventory implements ITickable {
//TODO FUTURE: Make AreaDescriptor for Teleposer perhaps?
public static final String TELEPOSER_RANGE = "teleposerRange";
private int previousInput;
public TileTeleposer() {
super(1, "teleposer");
}
@Override
public void deserialize(CompoundNBT tagCompound) {
super.deserialize(tagCompound);
previousInput = tagCompound.getInt(Constants.NBT.PREVIOUS_INPUT);
}
@Override
public CompoundNBT serialize(CompoundNBT tagCompound) {
super.serialize(tagCompound);
tagCompound.putInt(Constants.NBT.PREVIOUS_INPUT, previousInput);
return tagCompound;
}
@Override
public void update() {
if (!getWorld().isRemote && canInitiateTeleport()) {
int currentInput = getWorld().getStrongPower(pos);
if (previousInput == 0 && currentInput != 0) {
initiateTeleport();
}
previousInput = currentInput;
if (world.getTotalWorldTime() % 100 == 0) {
ItemStack focusStack = getStackInSlot(0);
if (!focusStack.isEmpty()) {
if (((ItemTelepositionFocus) focusStack.getItem()).getBinding(focusStack) != null)
SubCommandTeleposer.teleposerSet.add(this);
else
SubCommandTeleposer.teleposerSet.remove(this);
} else
SubCommandTeleposer.teleposerSet.remove(this);
}
}
}
public void initiateTeleport() {
if (!getWorld().isRemote && canInitiateTeleport() && getBlockType() instanceof BlockTeleposer) {
ItemStack focusStack = getStackInSlot(0);
ItemTelepositionFocus focus = (ItemTelepositionFocus) focusStack.getItem();
Binding binding = focus.getBinding(focusStack);
if (binding == null)
return;
BlockPos focusPos = focus.getBlockPos(focusStack);
World focusWorld = focus.getWorld(focusStack);
if (focusWorld == null)
return;
TileEntity boundTile = focusWorld.getTileEntity(focusPos);
if (boundTile instanceof TileTeleposer && boundTile != this) {
final int focusLevel = (focusStack.getItemDamage() + 1);
final int lpToBeDrained = (int) (0.5F * Math.sqrt((pos.getX() - focusPos.getX()) * (pos.getX() - focusPos.getX()) + (pos.getY() - focusPos.getY() + 1) * (pos.getY() - focusPos.getY() + 1) + (pos.getZ() - focusPos.getZ()) * (pos.getZ() - focusPos.getZ())));
if (NetworkHelper.syphonFromContainer(focusStack, SoulTicket.block(world, pos, lpToBeDrained * (focusLevel * 2 - 1) * (focusLevel * 2 - 1) * (focusLevel * 2 - 1)))) {
int blocksTransported = 0;
for (int i = -(focusLevel - 1); i <= (focusLevel - 1); i++) {
for (int j = 0; j <= (focusLevel * 2 - 2); j++) {
for (int k = -(focusLevel - 1); k <= (focusLevel - 1); k++) {
TeleposeEvent event = new TeleposeEvent(getWorld(), pos.add(i, 1 + j, k), focusWorld, focusPos.add(i, 1 + j, k));
if (!MinecraftForge.EVENT_BUS.post(event) && Utils.swapLocations(event.initalWorld, event.initialBlockPos, event.finalWorld, event.finalBlockPos)) {
blocksTransported++;
}
}
}
}
NetworkHelper.syphonFromContainer(focusStack, SoulTicket.item(focusStack, world, pos, lpToBeDrained * blocksTransported));
List<Entity> originalWorldEntities;
List<Entity> focusWorldEntities;
AxisAlignedBB originalArea = new AxisAlignedBB(pos.getX(), pos.getY() + 1, pos.getZ(), pos.getX() + 1, Math.min(focusWorld.getHeight(), pos.getY() + 2 * focusLevel), pos.getZ() + 1).expand(focusLevel - 1, 0, focusLevel - 1);
originalWorldEntities = getWorld().getEntitiesWithinAABB(Entity.class, originalArea);
AxisAlignedBB focusArea = new AxisAlignedBB(focusPos.getX(), focusPos.getY() + 1, focusPos.getZ(), focusPos.getX() + 1, Math.min(focusWorld.getHeight(), focusPos.getY() + 2 * focusLevel), focusPos.getZ() + 1).expand(focusLevel - 1, 0, focusLevel - 1);
focusWorldEntities = focusWorld.getEntitiesWithinAABB(Entity.class, focusArea);
UUID bindingOwnerID = binding.getOwnerId();
if (focusWorld.equals(getWorld())) {
if (!originalWorldEntities.isEmpty()) {
for (Entity entity : originalWorldEntities) {
TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, true));
}
}
if (!focusWorldEntities.isEmpty()) {
for (Entity entity : focusWorldEntities) {
TeleportQueue.getInstance().addITeleport(new Teleports.TeleportSameDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, true));
}
}
} else {
if (!originalWorldEntities.isEmpty()) {
for (Entity entity : originalWorldEntities) {
TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, getWorld(), focusWorld.provider.getDimension(), true));
}
}
if (!focusWorldEntities.isEmpty()) {
for (Entity entity : focusWorldEntities) {
TeleportQueue.getInstance().addITeleport(new Teleports.TeleportToDim(new BlockPos(entity.posX - pos.getX() + focusPos.getX(), entity.posY - pos.getY() + focusPos.getY(), entity.posZ - pos.getZ() + focusPos.getZ()), entity, bindingOwnerID, focusWorld, getWorld().provider.getDimension(), true));
}
}
}
}
}
}
}
private boolean canInitiateTeleport() {
ItemStack focusStack = getStackInSlot(0);
return !focusStack.isEmpty() && focusStack.getItem() instanceof ItemTelepositionFocus && ((ItemTelepositionFocus) focusStack.getItem()).getBinding(focusStack) != null;
}
}

View file

@ -1,120 +1,138 @@
package WayofTime.bloodmagic.tile.base;
package wayoftime.bloodmagic.tile.base;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
/**
* Base tile class.
* <p>
* Handles data syncing and core data writing/reading.
*/
public class TileBase extends TileEntity {
public abstract class TileBase extends TileEntity
{
public TileBase(TileEntityType<?> type)
{
super(type);
}
@Override
public final void deserializeNBT(CompoundNBT nbt) {
super.deserializeNBT(nbt);
deserializeBase(nbt);
deserialize(nbt);
}
/**
* read method
*/
@Override
public final void read(BlockState state, CompoundNBT compound)
{
super.read(state, compound);
deserializeBase(compound);
deserialize(compound);
}
@Override
public final CompoundNBT serializeNBT() {
CompoundNBT tag = super.serializeNBT();
serializeBase(tag);
return serialize(tag);
}
@Override
public final CompoundNBT write(CompoundNBT compound)
{
super.write(compound);
serializeBase(compound);
return serialize(compound);
}
/**
* Called by {@link #deserializeNBT(CompoundNBT)}
* <p>
* Internal data (such as coordinates) are handled for you. Just read the data you need.
*
* @param tagCompound - The tag compound to read from
*/
public void deserialize(CompoundNBT tagCompound) {
/**
* Called by {@link #func_230337_a_(BlockState, CompoundNBT)}
* <p>
* Internal data (such as coordinates) are handled for you. Just read the data
* you need.
*
* @param tagCompound - The tag compound to read from
*/
public void deserialize(CompoundNBT tagCompound)
{
}
}
/**
* Package private method for reading base data from the tag compound.
*
* @param tagCompound - The tag compound to read from
* @see TileTicking
*/
void deserializeBase(CompoundNBT tagCompound) {
/**
* Package private method for reading base data from the tag compound.
*
* @param tagCompound - The tag compound to read from
* @see TileTicking
*/
void deserializeBase(CompoundNBT tagCompound)
{
}
}
/**
* Called by {@link #serializeNBT()}
* <p>
* Internal data (such as coordinates) are handled for you. Just read the data you need.
*
* @param tagCompound - The tag compound to write to.
* @return the modified tag compound
*/
public CompoundNBT serialize(CompoundNBT tagCompound) {
return tagCompound;
}
/**
* Called by {@link #writeToNBT(CompoundNBT)}
* <p>
* Internal data (such as coordinates) are handled for you. Just read the data
* you need.
*
* @param tagCompound - The tag compound to write to.
* @return the modified tag compound
*/
public CompoundNBT serialize(CompoundNBT tagCompound)
{
return tagCompound;
}
/**
* Package private method for writing base data to the tag compound.
*
* @param tagCompound - The tag compound to write to.
* @return the modified tag compound
* @see TileTicking
*/
CompoundNBT serializeBase(CompoundNBT tagCompound)
{
return tagCompound;
}
/**
* Package private method for writing base data to the tag compound.
*
* @param tagCompound - The tag compound to write to.
* @return the modified tag compound
* @see TileTicking
*/
CompoundNBT serializeBase(CompoundNBT tagCompound) {
return tagCompound;
}
public void notifyUpdate()
{
BlockState state = getWorld().getBlockState(getPos());
getWorld().notifyBlockUpdate(getPos(), state, state, 3);
}
public void notifyUpdate() {
BlockState state = getWorld().getBlockState(getPos());
getWorld().notifyBlockUpdate(getPos(), state, state, 3);
}
// // Data syncing
//
// @Override
// public boolean shouldRefresh(World world, BlockPos pos, BlockState oldState, BlockState newState)
// {
// return oldState.getBlock() != newState.getBlock();
// }
// Data syncing
@Override
public final SUpdateTileEntityPacket getUpdatePacket()
{
return new SUpdateTileEntityPacket(getPos(), -999, getUpdateTag());
}
@Override
public boolean shouldRefresh(World world, BlockPos pos, BlockState oldState, BlockState newState) {
return oldState.getBlock() != newState.getBlock();
}
// @Override
// public void handleUpdateTag(BlockState state, CompoundNBT tag)
// {
// read(state, tag);
// }
@Override
public final SUpdateTileEntityPacket getUpdatePacket() {
return new SUpdateTileEntityPacket(getPos(), -999, serializeNBT());
}
@Override
@OnlyIn(Dist.CLIENT)
public final void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt)
{
super.onDataPacket(net, pkt);
handleUpdateTag(getBlockState(), pkt.getNbtCompound());
}
@Override
@SideOnly(Side.CLIENT)
public final void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) {
super.onDataPacket(net, pkt);
deserialize(pkt.getNbtCompound());
onDataPacketClientReceived();
}
@Override
public final CompoundNBT getUpdateTag()
{
return write(new CompoundNBT());
}
/**
* Hook for performing client side updates after data packets are received and processed
*/
protected void onDataPacketClientReceived() {
// noop
}
@Override
public final CompoundNBT getUpdateTag() {
return serializeNBT();
}
@Override
public final void handleUpdateTag(CompoundNBT tag) {
deserializeNBT(tag);
}
}
@Override
public final void handleUpdateTag(BlockState state, CompoundNBT tag)
{
read(state, tag);
}
}

View file

@ -1,55 +0,0 @@
package WayofTime.bloodmagic.tile.base;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
/**
* Base class for tiles that tick. Allows disabling the ticking programmatically.
*/
// TODO - Move implementations that depend on existed ticks to new methods from here.
public abstract class TileTicking extends TileBase implements ITickableTileEntity {
private int ticksExisted;
private boolean shouldTick = true;
@Override
public final void tick() {
if (shouldTick()) {
ticksExisted++;
onUpdate();
}
}
@Override
void deserializeBase(CompoundNBT tagCompound) {
this.ticksExisted = tagCompound.getInt("ticksExisted");
this.shouldTick = tagCompound.getBoolean("shouldTick");
}
@Override
CompoundNBT serializeBase(CompoundNBT tagCompound) {
tagCompound.putInt("ticksExisted", getTicksExisted());
tagCompound.putBoolean("shouldTick", shouldTick());
return tagCompound;
}
/**
* Called every tick that {@link #shouldTick()} is true.
*/
public abstract void onUpdate();
public int getTicksExisted() {
return ticksExisted;
}
public void resetLifetime() {
ticksExisted = 0;
}
public boolean shouldTick() {
return shouldTick;
}
public void setShouldTick(boolean shouldTick) {
this.shouldTick = shouldTick;
}
}

View file

@ -1,123 +0,0 @@
package WayofTime.bloodmagic.tile.container;
import WayofTime.bloodmagic.orb.IBloodOrb;
import WayofTime.bloodmagic.tile.TileAlchemyTable;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
public class ContainerAlchemyTable extends Container {
private final IInventory tileTable;
public ContainerAlchemyTable(PlayerInventory inventoryPlayer, IInventory tileTable) {
this.tileTable = tileTable;
this.addSlotToContainer(new Slot(tileTable, 0, 62, 15));
this.addSlotToContainer(new Slot(tileTable, 1, 80, 51));
this.addSlotToContainer(new Slot(tileTable, 2, 62, 87));
this.addSlotToContainer(new Slot(tileTable, 3, 26, 87));
this.addSlotToContainer(new Slot(tileTable, 4, 8, 51));
this.addSlotToContainer(new Slot(tileTable, 5, 26, 15));
this.addSlotToContainer(new Slot(tileTable, TileAlchemyTable.toolSlot, 152, 33));
this.addSlotToContainer(new SlotOrb(tileTable, TileAlchemyTable.orbSlot, 152, 69));
this.addSlotToContainer(new SlotOutput(tileTable, TileAlchemyTable.outputSlot, 44, 51));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 123 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 181));
}
}
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
PlayerInventory inventoryPlayer = player.inventory;
if (slotId < 6 && slotId >= 0) {
Slot slot = this.getSlot(slotId);
if (!slot.getHasStack() && inventoryPlayer.getItemStack().isEmpty()) {
((TileAlchemyTable) tileTable).toggleInputSlotAccessible(slotId);
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (index == 8) {
if (!this.mergeItemStack(itemstack1, 9, 9 + 36, true)) {
return ItemStack.EMPTY;
}
slot.onSlotChange(itemstack1, itemstack);
} else if (index > 8) {
if (itemstack1.getItem() instanceof IBloodOrb) {
if (!this.mergeItemStack(itemstack1, 7, 8, false)) //TODO: Add alchemy tools to list
{
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(itemstack1, 0, 6, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(itemstack1, 9, 9 + 36, false)) {
return ItemStack.EMPTY;
}
if (itemstack1.getCount() == 0) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return this.tileTable.isUsableByPlayer(playerIn);
}
private class SlotOrb extends Slot {
public SlotOrb(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean isItemValid(ItemStack itemStack) {
return itemStack.getItem() instanceof IBloodOrb;
}
}
private class SlotOutput extends Slot {
public SlotOutput(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean isItemValid(ItemStack stack) {
return false;
}
}
}

View file

@ -1,235 +0,0 @@
package WayofTime.bloodmagic.tile.container;
import WayofTime.bloodmagic.item.inventory.ItemInventory;
import WayofTime.bloodmagic.item.routing.IRoutingFilterProvider;
import WayofTime.bloodmagic.tile.routing.TileFilteredRoutingNode;
import WayofTime.bloodmagic.util.GhostItemHelper;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
public class ContainerItemRoutingNode extends Container {
private final IInventory tileItemRoutingNode;
private final TileFilteredRoutingNode inventory;
public int lastGhostSlotClicked = -1;
// private final ItemInventory itemInventory;
private int slotsOccupied;
public ContainerItemRoutingNode(PlayerInventory inventoryPlayer, IInventory tileItemRoutingNode) {
this.tileItemRoutingNode = tileItemRoutingNode;
inventory = (TileFilteredRoutingNode) tileItemRoutingNode;
this.addSlotToContainer(new SlotItemFilter(this, tileItemRoutingNode, 0, 8, 33));
ItemInventory itemInventory = inventory.itemInventory;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
addSlotToContainer(new SlotGhostItem(itemInventory, j + i * 3, 26 + j * 18, 15 + i * 18));
}
}
slotsOccupied = 10;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 87 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 145));
}
}
public void resetItemInventory(ItemStack masterStack) {
inventory.itemInventory.initializeInventory(masterStack);
}
/**
* Overridden in order to handle ghost item slots.
*/
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
PlayerInventory inventoryPlayer = player.inventory;
// if (!player.worldObj.isRemote)
{
if (slotId >= 0) {
Slot slot = this.inventorySlots.get(slotId);
if (slot instanceof SlotGhostItem) //TODO: make the slot clicking work!
{
lastGhostSlotClicked = slot.getSlotIndex();
if ((dragType == 0 || dragType == 1)) {
ItemStack slotStack = slot.getStack();
ItemStack heldStack = inventoryPlayer.getItemStack();
if (dragType == 0) //Left mouse click-eth
{
{
if (heldStack.isEmpty() && !slotStack.isEmpty()) {
//I clicked on the slot with an empty hand. Selecting!
} else if (!heldStack.isEmpty() && slotStack.isEmpty()) {
if (!((SlotGhostItem) slot).canBeAccessed()) {
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
ItemStack copyStack = heldStack.copy();
GhostItemHelper.setItemGhostAmount(copyStack, 0);
copyStack.setCount(1);
slot.putStack(copyStack);
ItemStack filterStack = this.inventorySlots.get(0).getStack();
if (filterStack.getItem() instanceof IRoutingFilterProvider) {
ItemStack filterCopy = ((IRoutingFilterProvider) filterStack.getItem()).getContainedStackForItem(filterStack, heldStack);
slot.putStack(filterCopy);
}
}
}
} else
//Right mouse click-eth away
{
slot.putStack(ItemStack.EMPTY);
}
}
}
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (index == 0) {
if (!this.mergeItemStack(itemstack1, slotsOccupied, slotsOccupied + 36, true)) {
return null;
}
slot.onSlotChange(itemstack1, itemstack);
} else if (index > 0) {
// return null;
if (itemstack1.getItem() instanceof IRoutingFilterProvider) // Change to check item is a filter
{
if (!this.mergeItemStack(itemstack1, 0, 1, false)) {
return ItemStack.EMPTY;
}
}
} else if (!this.mergeItemStack(itemstack1, slotsOccupied, 36 + slotsOccupied, false)) {
return ItemStack.EMPTY;
}
if (itemstack1.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return this.tileItemRoutingNode.isUsableByPlayer(playerIn);
}
private class SlotItemFilter extends Slot {
public ContainerItemRoutingNode container;
public TileFilteredRoutingNode inventory;
public SlotItemFilter(ContainerItemRoutingNode container, IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
this.container = container;
this.inventory = (TileFilteredRoutingNode) inventory;
}
@Override
public boolean isItemValid(ItemStack itemStack) {
return itemStack.getItem() instanceof IRoutingFilterProvider; //TODO: Create a new Item that holds the filter.
}
@Override
public void onSlotChanged() {
super.onSlotChanged();
container.resetItemInventory(getStack());
for (int i = 1; i <= 9; i++) {
Slot slot = container.getSlot(i);
slot.onSlotChanged();
}
}
@Override
public ItemStack getStack() {
return this.inventory.getStackInSlot(getActiveSlot());
}
@Override
public void putStack(@Nullable ItemStack stack) {
this.inventory.setInventorySlotContents(getActiveSlot(), stack);
this.onSlotChanged();
}
@Override
public ItemStack decrStackSize(int amount) {
return this.inventory.decrStackSize(getActiveSlot(), amount);
}
public int getActiveSlot() {
return inventory.currentActiveSlot;
}
}
private class SlotGhostItem extends Slot {
private ItemInventory itemInv;
public SlotGhostItem(ItemInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
itemInv = inventory;
}
@Override
public boolean isItemValid(ItemStack stack) {
return false;
}
@Override
public boolean canTakeStack(PlayerEntity playerIn) {
return false;
}
// @Override
// public boolean isHere(IInventory inv, int slotIn)
// {
// return itemInv.canInventoryBeManipulated() && super.isHere(inv, slotIn);
// }
public boolean canBeAccessed() {
return itemInv.canInventoryBeManipulated();
}
}
}

View file

@ -1,20 +0,0 @@
package WayofTime.bloodmagic.tile.container;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.IInventory;
public class ContainerMasterRoutingNode extends Container {
private final IInventory tileMasterRoutingNode;
public ContainerMasterRoutingNode(PlayerInventory inventoryPlayer, IInventory tileMasterRoutingNode) {
this.tileMasterRoutingNode = tileMasterRoutingNode;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return this.tileMasterRoutingNode.isUsableByPlayer(playerIn);
}
}

View file

@ -1,105 +0,0 @@
package WayofTime.bloodmagic.tile.container;
import WayofTime.bloodmagic.soul.IDemonWill;
import WayofTime.bloodmagic.soul.IDemonWillGem;
import WayofTime.bloodmagic.tile.TileSoulForge;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
public class ContainerSoulForge extends Container {
private final IInventory tileForge;
public ContainerSoulForge(PlayerInventory inventoryPlayer, IInventory tileForge) {
this.tileForge = tileForge;
this.addSlotToContainer(new Slot(tileForge, 0, 8, 15));
this.addSlotToContainer(new Slot(tileForge, 1, 80, 15));
this.addSlotToContainer(new Slot(tileForge, 2, 8, 87));
this.addSlotToContainer(new Slot(tileForge, 3, 80, 87));
this.addSlotToContainer(new SlotSoul(tileForge, TileSoulForge.soulSlot, 152, 51));
this.addSlotToContainer(new SlotOutput(tileForge, TileSoulForge.outputSlot, 44, 51));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 123 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 181));
}
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
ItemStack itemstack = ItemStack.EMPTY;
Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
if (index == 5) {
if (!this.mergeItemStack(itemstack1, 6, 6 + 36, true)) {
return ItemStack.EMPTY;
}
slot.onSlotChange(itemstack1, itemstack);
} else if (index > 5) {
if (itemstack1.getItem() instanceof IDemonWill || itemstack1.getItem() instanceof IDemonWillGem) {
if (!this.mergeItemStack(itemstack1, 4, 5, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(itemstack1, 0, 4, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(itemstack1, 6, 42, false)) {
return ItemStack.EMPTY;
}
if (itemstack1.getCount() == 0) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if (itemstack1.getCount() == itemstack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTake(playerIn, itemstack1);
}
return itemstack;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return this.tileForge.isUsableByPlayer(playerIn);
}
private class SlotSoul extends Slot {
public SlotSoul(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean isItemValid(ItemStack itemStack) {
return itemStack.getItem() instanceof IDemonWillGem || itemStack.getItem() instanceof IDemonWill;
}
}
private class SlotOutput extends Slot {
public SlotOutput(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean isItemValid(ItemStack stack) {
return false;
}
}
}

View file

@ -1,80 +0,0 @@
package WayofTime.bloodmagic.tile.container;
import WayofTime.bloodmagic.item.ItemTelepositionFocus;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
public class ContainerTeleposer extends Container {
private final IInventory tileTeleposer;
public ContainerTeleposer(PlayerInventory inventoryPlayer, IInventory tileTeleposer) {
this.tileTeleposer = tileTeleposer;
this.addSlotToContainer(new SlotTeleposer(tileTeleposer, 0, 80, 33));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 57 + i * 18));
}
}
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 115));
}
}
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int slot) {
ItemStack stack = ItemStack.EMPTY;
Slot slotObject = inventorySlots.get(slot);
int slots = inventorySlots.size();
if (slotObject != null && slotObject.getHasStack()) {
ItemStack stackInSlot = slotObject.getStack();
stack = stackInSlot.copy();
if (stack.getItem() instanceof ItemTelepositionFocus) {
if (slot <= slots) {
if (!this.mergeItemStack(stackInSlot, 0, slots, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(stackInSlot, slots, 36 + slots, false)) {
return ItemStack.EMPTY;
}
}
if (stackInSlot.getCount() == 0) {
slotObject.putStack(ItemStack.EMPTY);
} else {
slotObject.onSlotChanged();
}
if (stackInSlot.getCount() == stack.getCount()) {
return ItemStack.EMPTY;
}
slotObject.onTake(player, stackInSlot);
}
return stack;
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return this.tileTeleposer.isUsableByPlayer(playerIn);
}
private class SlotTeleposer extends Slot {
public SlotTeleposer(IInventory inventory, int slotIndex, int x, int y) {
super(inventory, slotIndex, x, y);
}
@Override
public boolean isItemValid(ItemStack itemStack) {
return itemStack.getItem() instanceof ItemTelepositionFocus;
}
}
}

View file

@ -1,119 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.item.inventory.ItemInventory;
import WayofTime.bloodmagic.util.GhostItemHelper;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.NonNullList;
public class TileFilteredRoutingNode extends TileRoutingNode implements ISidedInventory {
public int currentActiveSlot = 0;
public int[] priorities = new int[6];
public ItemInventory itemInventory = new ItemInventory(ItemStack.EMPTY, 9, "");
public TileFilteredRoutingNode(int size, String name) {
super(size, name);
}
public ItemStack getFilterStack(Direction side) {
int index = side.getIndex();
return getStackInSlot(index);
}
public void setGhostItemAmount(int ghostItemSlot, int amount) {
ItemStack stack = itemInventory.getStackInSlot(ghostItemSlot);
if (!stack.isEmpty()) {
GhostItemHelper.setItemGhostAmount(stack, amount);
}
this.markDirty();
}
@Override
public boolean isInventoryConnectedToSide(Direction side) {
return true;
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
currentActiveSlot = tag.getInt("currentSlot");
priorities = tag.getIntArray(Constants.NBT.ROUTING_PRIORITY);
if (priorities.length != 6) {
priorities = new int[6];
}
if (!tag.getBoolean("updated")) {
ListNBT tags = tag.getList("Items", 10);
inventory = NonNullList.withSize(getSizeInventory(), ItemStack.EMPTY);
for (int i = 0; i < tags.tagCount(); i++) {
if (!isSyncedSlot(i)) {
CompoundNBT data = tags.getCompound(i);
byte j = data.getByte("Slot");
if (j == 0) {
inventory.set(i, new ItemStack(data));
} else if (j >= 1 && j < inventory.size() + 1) {
inventory.set(j - 1, new ItemStack(data));
}
}
}
}
itemInventory = new ItemInventory(getStackInSlot(currentActiveSlot), 9, "");
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
tag.putInt("currentSlot", currentActiveSlot);
tag.putIntArray(Constants.NBT.ROUTING_PRIORITY, priorities);
tag.putBoolean("updated", true);
return tag;
}
public void swapFilters(int requestedSlot) {
currentActiveSlot = requestedSlot;
itemInventory.initializeInventory(getStackInSlot(currentActiveSlot));
this.markDirty();
}
@Override
public int[] getSlotsForFace(Direction side) {
return new int[0];
}
@Override
public boolean canInsertItem(int index, ItemStack itemStackIn, Direction direction) {
return false;
}
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction) {
return false;
}
@Override
public int getPriority(Direction side) {
return priorities[side.getIndex()];
}
public void incrementCurrentPriotiryToMaximum(int max) {
priorities[currentActiveSlot] = Math.min(priorities[currentActiveSlot] + 1, max);
BlockState state = getWorld().getBlockState(pos);
getWorld().notifyBlockUpdate(pos, state, state, 3);
}
public void decrementCurrentPriority() {
priorities[currentActiveSlot] = Math.max(priorities[currentActiveSlot] - 1, 0);
BlockState state = getWorld().getBlockState(pos);
getWorld().notifyBlockUpdate(pos, state, state, 3);
}
}

View file

@ -1,73 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
import WayofTime.bloodmagic.item.routing.IFluidFilterProvider;
import WayofTime.bloodmagic.item.routing.IItemFilterProvider;
import WayofTime.bloodmagic.routing.*;
import WayofTime.bloodmagic.util.Utils;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
public class TileInputRoutingNode extends TileFilteredRoutingNode implements IInputItemRoutingNode, IInputFluidRoutingNode {
public TileInputRoutingNode() {
super(6, "inputNode");
}
@Override
public boolean isInput(Direction side) {
return true;
}
@Override
public IItemFilter getInputFilterForSide(Direction side) {
TileEntity tile = getWorld().getTileEntity(pos.offset(side));
if (tile != null) {
IItemHandler handler = Utils.getInventory(tile, side.getOpposite());
if (handler != null) {
ItemStack filterStack = this.getFilterStack(side);
if (filterStack.isEmpty()) {
IItemFilter filter = new DefaultItemFilter();
filter.initializeFilter(null, tile, handler, false);
return filter;
} else if (!(filterStack.getItem() instanceof IItemFilterProvider)) {
return null;
}
IItemFilterProvider filter = (IItemFilterProvider) filterStack.getItem();
return filter.getInputItemFilter(filterStack, tile, handler);
}
}
return null;
}
@Override
public boolean isFluidInput(Direction side) {
return true;
}
@Override
public IFluidFilter getInputFluidFilterForSide(Direction side) {
TileEntity tile = getWorld().getTileEntity(pos.offset(side));
if (tile != null && tile.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side)) {
IFluidHandler handler = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side);
ItemStack filterStack = this.getFilterStack(side);
if (filterStack == null || !(filterStack.getItem() instanceof IFluidFilterProvider)) {
return null;
}
return ((IFluidFilterProvider) filterStack.getItem()).getInputFluidFilter(filterStack, tile, handler);
}
return null;
}
@Override
public boolean isTankConnectedToSide(Direction side) {
return true;
}
}

View file

@ -1,7 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
public class TileItemRoutingNode extends TileRoutingNode {
public TileItemRoutingNode() {
super(0, "itemNode");
}
}

View file

@ -1,405 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.soul.EnumDemonWillType;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
import WayofTime.bloodmagic.routing.*;
import WayofTime.bloodmagic.tile.TileInventory;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.*;
import java.util.Map.Entry;
public class TileMasterRoutingNode extends TileInventory implements IMasterRoutingNode, ITickable {
public static final int tickRate = 20;
private int currentInput;
// A list of connections
private TreeMap<BlockPos, List<BlockPos>> connectionMap = new TreeMap<>();
private List<BlockPos> generalNodeList = new LinkedList<>();
private List<BlockPos> outputNodeList = new LinkedList<>();
private List<BlockPos> inputNodeList = new LinkedList<>();
public TileMasterRoutingNode() {
super(0, "masterRoutingNode");
}
@Override
public void update() {
if (!getWorld().isRemote) {
// currentInput = getWorld().isBlockIndirectlyGettingPowered(pos);
currentInput = getWorld().getStrongPower(pos);
// System.out.println(currentInput);
}
if (getWorld().isRemote || getWorld().getTotalWorldTime() % tickRate != 0) //Temporary tick rate solver
{
return;
}
Map<Integer, List<IItemFilter>> outputMap = new TreeMap<>();
Map<Integer, List<IFluidFilter>> outputFluidMap = new TreeMap<>();
for (BlockPos outputPos : outputNodeList) {
TileEntity outputTile = getWorld().getTileEntity(outputPos);
if (this.isConnected(new LinkedList<>(), outputPos)) {
if (outputTile instanceof IOutputItemRoutingNode) {
IOutputItemRoutingNode outputNode = (IOutputItemRoutingNode) outputTile;
for (Direction facing : Direction.VALUES) {
if (!outputNode.isInventoryConnectedToSide(facing) || !outputNode.isOutput(facing)) {
continue;
}
IItemFilter filter = outputNode.getOutputFilterForSide(facing);
if (filter != null) {
int priority = outputNode.getPriority(facing);
if (outputMap.containsKey(priority)) {
outputMap.get(priority).add(filter);
} else {
List<IItemFilter> filterList = new LinkedList<>();
filterList.add(filter);
outputMap.put(priority, filterList);
}
}
}
}
if (outputTile instanceof IOutputFluidRoutingNode) {
IOutputFluidRoutingNode outputNode = (IOutputFluidRoutingNode) outputTile;
for (Direction facing : Direction.VALUES) {
if (!outputNode.isTankConnectedToSide(facing) || !outputNode.isFluidOutput(facing)) {
continue;
}
IFluidFilter filter = outputNode.getOutputFluidFilterForSide(facing);
if (filter != null) {
int priority = outputNode.getPriority(facing);
if (outputFluidMap.containsKey(priority)) {
outputFluidMap.get(priority).add(filter);
} else {
List<IFluidFilter> filterList = new LinkedList<>();
filterList.add(filter);
outputFluidMap.put(priority, filterList);
}
}
}
}
}
}
Map<Integer, List<IItemFilter>> inputMap = new TreeMap<>();
Map<Integer, List<IFluidFilter>> inputFluidMap = new TreeMap<>();
for (BlockPos inputPos : inputNodeList) {
TileEntity inputTile = getWorld().getTileEntity(inputPos);
if (this.isConnected(new LinkedList<>(), inputPos)) {
if (inputTile instanceof IInputItemRoutingNode) {
IInputItemRoutingNode inputNode = (IInputItemRoutingNode) inputTile;
for (Direction facing : Direction.VALUES) {
if (!inputNode.isInventoryConnectedToSide(facing) || !inputNode.isInput(facing)) {
continue;
}
IItemFilter filter = inputNode.getInputFilterForSide(facing);
if (filter != null) {
int priority = inputNode.getPriority(facing);
if (inputMap.containsKey(priority)) {
inputMap.get(priority).add(filter);
} else {
List<IItemFilter> filterList = new LinkedList<>();
filterList.add(filter);
inputMap.put(priority, filterList);
}
}
}
}
if (inputTile instanceof IInputFluidRoutingNode) {
IInputFluidRoutingNode inputNode = (IInputFluidRoutingNode) inputTile;
for (Direction facing : Direction.VALUES) {
if (!inputNode.isTankConnectedToSide(facing) || !inputNode.isFluidInput(facing)) {
continue;
}
IFluidFilter filter = inputNode.getInputFluidFilterForSide(facing);
if (filter != null) {
int priority = inputNode.getPriority(facing);
if (inputFluidMap.containsKey(priority)) {
inputFluidMap.get(priority).add(filter);
} else {
List<IFluidFilter> filterList = new LinkedList<>();
filterList.add(filter);
inputFluidMap.put(priority, filterList);
}
}
}
}
}
}
int maxTransfer = this.getMaxTransferForDemonWill(WorldDemonWillHandler.getCurrentWill(getWorld(), pos, EnumDemonWillType.DEFAULT));
int maxFluidTransfer = 1000;
for (Entry<Integer, List<IItemFilter>> outputEntry : outputMap.entrySet()) {
List<IItemFilter> outputList = outputEntry.getValue();
for (IItemFilter outputFilter : outputList) {
for (Entry<Integer, List<IItemFilter>> inputEntry : inputMap.entrySet()) {
List<IItemFilter> inputList = inputEntry.getValue();
for (IItemFilter inputFilter : inputList) {
maxTransfer -= inputFilter.transferThroughInputFilter(outputFilter, maxTransfer);
if (maxTransfer <= 0) {
return;
}
}
}
}
}
for (Entry<Integer, List<IFluidFilter>> outputEntry : outputFluidMap.entrySet()) {
List<IFluidFilter> outputList = outputEntry.getValue();
for (IFluidFilter outputFilter : outputList) {
for (Entry<Integer, List<IFluidFilter>> inputEntry : inputFluidMap.entrySet()) {
List<IFluidFilter> inputList = inputEntry.getValue();
for (IFluidFilter inputFilter : inputList) {
maxFluidTransfer -= inputFilter.transferThroughInputFilter(outputFilter, maxFluidTransfer);
if (maxFluidTransfer <= 0) {
return;
}
}
}
}
}
}
public int getMaxTransferForDemonWill(double will) {
return 64;
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
ListNBT tags = new ListNBT();
for (BlockPos pos : generalNodeList) {
CompoundNBT posTag = new CompoundNBT();
posTag.putInt(Constants.NBT.X_COORD, pos.getX());
posTag.putInt(Constants.NBT.Y_COORD, pos.getY());
posTag.putInt(Constants.NBT.Z_COORD, pos.getZ());
tags.appendTag(posTag);
}
tag.put(Constants.NBT.ROUTING_MASTER_GENERAL, tags);
tags = new ListNBT();
for (BlockPos pos : inputNodeList) {
CompoundNBT posTag = new CompoundNBT();
posTag.putInt(Constants.NBT.X_COORD, pos.getX());
posTag.putInt(Constants.NBT.Y_COORD, pos.getY());
posTag.putInt(Constants.NBT.Z_COORD, pos.getZ());
tags.appendTag(posTag);
}
tag.put(Constants.NBT.ROUTING_MASTER_INPUT, tags);
tags = new ListNBT();
for (BlockPos pos : outputNodeList) {
CompoundNBT posTag = new CompoundNBT();
posTag.putInt(Constants.NBT.X_COORD, pos.getX());
posTag.putInt(Constants.NBT.Y_COORD, pos.getY());
posTag.putInt(Constants.NBT.Z_COORD, pos.getZ());
tags.appendTag(posTag);
}
tag.put(Constants.NBT.ROUTING_MASTER_OUTPUT, tags);
return tag;
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
ListNBT tags = tag.getList(Constants.NBT.ROUTING_MASTER_GENERAL, 10);
for (int i = 0; i < tags.tagCount(); i++) {
CompoundNBT blockTag = tags.getCompound(i);
BlockPos newPos = new BlockPos(blockTag.getInt(Constants.NBT.X_COORD), blockTag.getInt(Constants.NBT.Y_COORD), blockTag.getInt(Constants.NBT.Z_COORD));
generalNodeList.add(newPos);
}
tags = tag.getList(Constants.NBT.ROUTING_MASTER_INPUT, 10);
for (int i = 0; i < tags.tagCount(); i++) {
CompoundNBT blockTag = tags.getCompound(i);
BlockPos newPos = new BlockPos(blockTag.getInt(Constants.NBT.X_COORD), blockTag.getInt(Constants.NBT.Y_COORD), blockTag.getInt(Constants.NBT.Z_COORD));
inputNodeList.add(newPos);
}
tags = tag.getList(Constants.NBT.ROUTING_MASTER_OUTPUT, 10);
for (int i = 0; i < tags.tagCount(); i++) {
CompoundNBT blockTag = tags.getCompound(i);
BlockPos newPos = new BlockPos(blockTag.getInt(Constants.NBT.X_COORD), blockTag.getInt(Constants.NBT.Y_COORD), blockTag.getInt(Constants.NBT.Z_COORD));
outputNodeList.add(newPos);
}
}
@Override
public boolean isConnected(List<BlockPos> path, BlockPos nodePos) {
//TODO: Figure out how to make it so the path is obtained
// if (!connectionMap.containsKey(nodePos))
// {
// return false;
// }
TileEntity tile = getWorld().getTileEntity(nodePos);
if (!(tile instanceof IRoutingNode)) {
// connectionMap.remove(nodePos);
return false;
}
IRoutingNode node = (IRoutingNode) tile;
List<BlockPos> connectionList = node.getConnected();
// List<BlockPos> testPath = path.subList(0, path.size());
path.add(nodePos);
for (BlockPos testPos : connectionList) {
if (path.contains(testPos)) {
continue;
}
if (testPos.equals(this.getPos()) && node.isConnectionEnabled(testPos)) {
// path.clear();
// path.addAll(testPath);
return true;
} else if (NodeHelper.isNodeConnectionEnabled(getWorld(), node, testPos)) {
if (isConnected(path, testPos)) {
// path.clear();
// path.addAll(testPath);
return true;
}
}
}
return false;
}
@Override
public boolean isConnectionEnabled(BlockPos testPos) {
return currentInput <= 0;
}
@Override
public void addNodeToList(IRoutingNode node) {
BlockPos newPos = node.getBlockPos();
if (!generalNodeList.contains(newPos)) {
generalNodeList.add(newPos);
}
if (node instanceof IInputItemRoutingNode && !inputNodeList.contains(newPos)) {
inputNodeList.add(newPos);
}
if (node instanceof IOutputItemRoutingNode && !outputNodeList.contains(newPos)) {
outputNodeList.add(newPos);
}
}
@Override
public void addConnections(BlockPos pos, List<BlockPos> connectionList) {
for (BlockPos testPos : connectionList) {
addConnection(pos, testPos);
}
}
@Override
public void addConnection(BlockPos pos1, BlockPos pos2) {
if (connectionMap.containsKey(pos1) && !connectionMap.get(pos1).contains(pos2)) {
connectionMap.get(pos1).add(pos2);
} else {
List<BlockPos> list = new LinkedList<>();
list.add(pos2);
connectionMap.put(pos1, list);
}
if (connectionMap.containsKey(pos2) && !connectionMap.get(pos2).contains(pos1)) {
connectionMap.get(pos2).add(pos1);
} else {
List<BlockPos> list = new LinkedList<>();
list.add(pos1);
connectionMap.put(pos2, list);
}
}
@Override
public void removeConnection(BlockPos pos1, BlockPos pos2) {
if (connectionMap.containsKey(pos1)) {
List<BlockPos> posList = connectionMap.get(pos1);
posList.remove(pos2);
if (posList.isEmpty()) {
connectionMap.remove(pos1);
}
}
if (connectionMap.containsKey(pos2)) {
List<BlockPos> posList = connectionMap.get(pos2);
posList.remove(pos1);
if (posList.isEmpty()) {
connectionMap.remove(pos2);
}
}
}
@Override
public void connectMasterToRemainingNode(World world, List<BlockPos> alreadyChecked, IMasterRoutingNode master) {
return;
}
@Override
public BlockPos getBlockPos() {
return this.getPos();
}
@Override
public List<BlockPos> getConnected() {
return new LinkedList<>();
}
@Override
public BlockPos getMasterPos() {
return this.getPos();
}
@Override
public boolean isMaster(IMasterRoutingNode master) {
return false;
}
@Override
public void addConnection(BlockPos pos1) {
// Empty
}
@Override
public void removeConnection(BlockPos pos1) {
generalNodeList.remove(pos1);
inputNodeList.remove(pos1);
outputNodeList.remove(pos1);
}
@Override
public void removeAllConnections() {
List<BlockPos> list = generalNodeList.subList(0, generalNodeList.size());
Iterator<BlockPos> itr = list.iterator();
while (itr.hasNext()) {
BlockPos testPos = itr.next();
TileEntity tile = getWorld().getTileEntity(testPos);
if (tile instanceof IRoutingNode) {
((IRoutingNode) tile).removeConnection(pos);
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(testPos), getWorld().getBlockState(testPos), 3);
}
itr.remove();
inputNodeList.remove(testPos);
outputNodeList.remove(testPos);
}
}
}

View file

@ -1,73 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
import WayofTime.bloodmagic.item.routing.IFluidFilterProvider;
import WayofTime.bloodmagic.item.routing.IItemFilterProvider;
import WayofTime.bloodmagic.routing.*;
import WayofTime.bloodmagic.util.Utils;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
public class TileOutputRoutingNode extends TileFilteredRoutingNode implements IOutputItemRoutingNode, IOutputFluidRoutingNode {
public TileOutputRoutingNode() {
super(6, "outputNode");
}
@Override
public boolean isOutput(Direction side) {
return true;
}
@Override
public IItemFilter getOutputFilterForSide(Direction side) {
TileEntity tile = getWorld().getTileEntity(pos.offset(side));
if (tile != null) {
IItemHandler handler = Utils.getInventory(tile, side.getOpposite());
if (handler != null) {
ItemStack filterStack = this.getFilterStack(side);
if (filterStack.isEmpty()) {
IItemFilter filter = new DefaultItemFilter();
filter.initializeFilter(null, tile, handler, true);
return filter;
} else if (!(filterStack.getItem() instanceof IItemFilterProvider)) {
return null;
}
IItemFilterProvider filter = (IItemFilterProvider) filterStack.getItem();
return filter.getOutputItemFilter(filterStack, tile, handler);
}
}
return null;
}
@Override
public boolean isFluidOutput(Direction side) {
return true;
}
@Override
public IFluidFilter getOutputFluidFilterForSide(Direction side) {
TileEntity tile = getWorld().getTileEntity(pos.offset(side));
if (tile != null && tile.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side)) {
IFluidHandler handler = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side);
ItemStack filterStack = this.getFilterStack(side);
if (filterStack == null || !(filterStack.getItem() instanceof IFluidFilterProvider)) {
return null;
}
return ((IFluidFilterProvider) filterStack.getItem()).getOutputFluidFilter(filterStack, tile, handler);
}
return null;
}
@Override
public boolean isTankConnectedToSide(Direction side) {
return true;
}
}

View file

@ -1,176 +0,0 @@
package WayofTime.bloodmagic.tile.routing;
import WayofTime.bloodmagic.util.Constants;
import WayofTime.bloodmagic.routing.IItemRoutingNode;
import WayofTime.bloodmagic.routing.IMasterRoutingNode;
import WayofTime.bloodmagic.routing.IRoutingNode;
import WayofTime.bloodmagic.tile.TileInventory;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.LinkedList;
import java.util.List;
public class TileRoutingNode extends TileInventory implements IRoutingNode, IItemRoutingNode, ITickable {
private int currentInput;
private BlockPos masterPos = BlockPos.ORIGIN;
private List<BlockPos> connectionList = new LinkedList<>();
public TileRoutingNode(int size, String name) {
super(size, name);
}
@Override
public void update() {
if (!getWorld().isRemote) {
currentInput = getWorld().getRedstonePowerFromNeighbors(pos);
// currentInput = getWorld().getStrongPower(pos);
}
}
@Override
public CompoundNBT serialize(CompoundNBT tag) {
super.serialize(tag);
CompoundNBT masterTag = new CompoundNBT();
masterTag.putInt(Constants.NBT.X_COORD, masterPos.getX());
masterTag.putInt(Constants.NBT.Y_COORD, masterPos.getY());
masterTag.putInt(Constants.NBT.Z_COORD, masterPos.getZ());
tag.put(Constants.NBT.ROUTING_MASTER, masterTag);
ListNBT tags = new ListNBT();
for (BlockPos pos : connectionList) {
CompoundNBT posTag = new CompoundNBT();
posTag.putInt(Constants.NBT.X_COORD, pos.getX());
posTag.putInt(Constants.NBT.Y_COORD, pos.getY());
posTag.putInt(Constants.NBT.Z_COORD, pos.getZ());
tags.add(posTag);
}
tag.put(Constants.NBT.ROUTING_CONNECTION, tags);
return tag;
}
@Override
public void deserialize(CompoundNBT tag) {
super.deserialize(tag);
connectionList.clear();
CompoundNBT masterTag = tag.getCompound(Constants.NBT.ROUTING_MASTER);
masterPos = new BlockPos(masterTag.getInt(Constants.NBT.X_COORD), masterTag.getInt(Constants.NBT.Y_COORD), masterTag.getInt(Constants.NBT.Z_COORD));
ListNBT tags = tag.getList(Constants.NBT.ROUTING_CONNECTION, 10);
for (int i = 0; i < tags.size(); i++) {
CompoundNBT blockTag = tags.getCompound(i);
BlockPos newPos = new BlockPos(blockTag.getInt(Constants.NBT.X_COORD), blockTag.getInt(Constants.NBT.Y_COORD), blockTag.getInt(Constants.NBT.Z_COORD));
connectionList.add(newPos);
}
}
@Override
public void removeAllConnections() {
TileEntity testTile = getWorld().getTileEntity(getMasterPos());
if (testTile instanceof IMasterRoutingNode) {
((IMasterRoutingNode) testTile).removeConnection(pos); // Remove this node from the master
}
for (BlockPos testPos : connectionList) {
TileEntity tile = getWorld().getTileEntity(testPos);
if (tile instanceof IRoutingNode) {
((IRoutingNode) tile).removeConnection(pos);
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(testPos), getWorld().getBlockState(testPos), 3);
}
}
connectionList.clear();
}
@Override
public void connectMasterToRemainingNode(World world, List<BlockPos> alreadyChecked, IMasterRoutingNode master) {
this.masterPos = master.getBlockPos();
List<BlockPos> connectedList = this.getConnected();
for (BlockPos testPos : connectedList) {
if (alreadyChecked.contains(testPos)) {
continue;
}
alreadyChecked.add(testPos);
TileEntity tile = world.getTileEntity(testPos);
if (!(tile instanceof IRoutingNode)) {
continue;
}
IRoutingNode node = (IRoutingNode) tile;
if (node.getMasterPos().equals(BlockPos.ORIGIN)) //If getMasterPos() returns the origin, the node is not connected to any master.
{
master.addNodeToList(node);
node.connectMasterToRemainingNode(world, alreadyChecked, master);
}
}
master.addConnections(this.getBlockPos(), connectedList);
}
@Override
public BlockPos getBlockPos() {
return this.getPos();
}
@Override
public List<BlockPos> getConnected() {
return connectionList;
}
@Override
public BlockPos getMasterPos() {
return masterPos;
}
@Override
public boolean isMaster(IMasterRoutingNode master) {
BlockPos checkPos = master.getBlockPos();
return checkPos.equals(getMasterPos());
}
@Override
public boolean isConnectionEnabled(BlockPos testPos) {
return currentInput <= 0;
}
@Override
public void addConnection(BlockPos pos1) {
if (!connectionList.contains(pos1)) {
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
connectionList.add(pos1);
}
}
@Override
public void removeConnection(BlockPos pos1) {
if (connectionList.contains(pos1)) {
connectionList.remove(pos1);
getWorld().notifyBlockUpdate(getPos(), getWorld().getBlockState(getPos()), getWorld().getBlockState(getPos()), 3);
}
if (pos1.equals(masterPos)) {
this.masterPos = BlockPos.ORIGIN;
}
}
@Override
public boolean isInventoryConnectedToSide(Direction side) {
return false;
}
@Override
public int getPriority(Direction side) {
return 0;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 10000;
}
}