Added Demon Pylon (currently no model) which pulls demon will from surrounding chunks into its chunk.

This commit is contained in:
WayofTime 2016-02-23 13:40:08 -05:00
parent 7104138e2b
commit 743af85a61
9 changed files with 306 additions and 170 deletions

View file

@ -1,33 +1,20 @@
package WayofTime.bloodmagic.tile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ITickable;
import WayofTime.bloodmagic.api.Constants;
import WayofTime.bloodmagic.api.ritual.AreaDescriptor;
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
import WayofTime.bloodmagic.api.soul.IDemonWillConduit;
import WayofTime.bloodmagic.api.soul.IDemonWillGem;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
public class TileDemonCrucible extends TileInventory implements ITickable, IDemonWillConduit
{
public AreaDescriptor checkArea = new AreaDescriptor.Rectangle(new BlockPos(-5, -5, -5), 11);
public List<BlockPos> conduitList = new ArrayList<BlockPos>(); //Offset list
public HashMap<EnumDemonWillType, Double> willMap = new HashMap<EnumDemonWillType, Double>();
public HashMap<EnumDemonWillType, Double> willMap = new HashMap<EnumDemonWillType, Double>(); //TODO: Change to DemonWillHolder
public final int maxWill = 100;
public final double maxTransferPerTick = 1;
public final double thresholdFill = 0.01;
public final double gemDrainRate = 10;
public int internalCounter = 0;
@ -45,26 +32,6 @@ public class TileDemonCrucible extends TileInventory implements ITickable, IDemo
return;
}
if (internalCounter % 100 == 0)
{
conduitList.clear();
List<BlockPos> posList = checkArea.getContainedPositions(pos);
for (BlockPos newPos : posList)
{
if (newPos.equals(pos))
{
continue;
}
TileEntity tile = worldObj.getTileEntity(newPos);
if (tile instanceof IDemonWillConduit)
{
conduitList.add(newPos.subtract(getPos()));
}
}
}
internalCounter++;
if (worldObj.isBlockPowered(getPos()))
@ -107,114 +74,14 @@ public class TileDemonCrucible extends TileInventory implements ITickable, IDemo
IDemonWillGem gemItem = (IDemonWillGem) stack.getItem();
for (EnumDemonWillType type : EnumDemonWillType.values())
{
if (!willMap.containsKey(type))
double currentAmount = WorldDemonWillHandler.getCurrentWill(worldObj, pos, type);
double drainAmount = Math.min(maxWill - currentAmount, gemDrainRate);
double filled = WorldDemonWillHandler.fillWillToMaximum(worldObj, pos, type, drainAmount, maxWill, false);
filled = gemItem.drainWill(type, stack, filled);
if (filled > 0)
{
willMap.put(type, 0d);
WorldDemonWillHandler.fillWillToMaximum(worldObj, pos, type, filled, maxWill, true);
}
if (willMap.get(type) < maxWill)
{
double drainAmount = Math.min(maxWill - willMap.get(type), gemDrainRate);
double drained = gemItem.drainWill(type, stack, drainAmount);
willMap.put(type, willMap.get(type) + drained);
}
}
}
}
double maxWeight = 0;
List<IDemonWillConduit> tileList = new ArrayList<IDemonWillConduit>();
Collections.shuffle(tileList);
Iterator<BlockPos> iterator = conduitList.iterator();
while (iterator.hasNext())
{
BlockPos newPos = pos.add(iterator.next());
TileEntity tile = worldObj.getTileEntity(newPos);
if (tile instanceof IDemonWillConduit)
{
maxWeight += ((IDemonWillConduit) tile).getWeight();
tileList.add((IDemonWillConduit) tile);
} else
{
iterator.remove();
}
}
if (maxWeight > 0)
{
for (EnumDemonWillType type : EnumDemonWillType.values())
{
List<IDemonWillConduit> copyTileList = new ArrayList<IDemonWillConduit>();
copyTileList.addAll(tileList);
double currentAmount = this.getCurrentWill(type);
if (currentAmount <= 0)
{
continue;
}
double transfered = 0;
double newMaxWeight = 0;
double transferTotalLastRound = 0;
int pass = 0;
final int maxPasses = 2;
while (pass < maxPasses && transfered < maxTransferPerTick && maxWeight > 0)
{
pass++;
newMaxWeight = 0;
Iterator<IDemonWillConduit> conduitIterator = copyTileList.iterator();
while (conduitIterator.hasNext())
{
IDemonWillConduit conduit = conduitIterator.next();
if (!conduit.canFill(type))
{
conduitIterator.remove();
continue;
}
newMaxWeight += conduit.getWeight();
double transfer = Math.min(currentAmount, conduit.getWeight() * (maxTransferPerTick - transferTotalLastRound) / maxWeight);
if (transfer <= 0)
{
conduitIterator.remove();
continue;
}
double conduitAmount = conduit.getCurrentWill(type);
if (currentAmount - conduitAmount <= thresholdFill) // Will only fill if this conduit's amount is greater than the conduit it is filling.
{
conduitIterator.remove();
continue;
}
transfer = conduit.fillDemonWill(type, transfer, false);
if (transfer > 0)
{
worldObj.markBlockForUpdate(((TileEntity) conduit).getPos());
conduit.fillDemonWill(type, transfer, true);
currentAmount -= transfer;
transfered += transfer;
} else
{
conduitIterator.remove();
}
}
maxWeight = newMaxWeight;
transferTotalLastRound = transfered;
}
if (currentAmount <= 0)
{
willMap.remove(type);
} else
{
willMap.put(type, currentAmount);
}
}
}
@ -236,14 +103,6 @@ public class TileDemonCrucible extends TileInventory implements ITickable, IDemo
willMap.put(type, amount);
}
}
NBTTagList tags = tag.getTagList(Constants.NBT.BLOCKPOS_CONNECTION, 10);
for (int i = 0; i < tags.tagCount(); i++)
{
NBTTagCompound blockTag = tags.getCompoundTagAt(i);
BlockPos newPos = new BlockPos(blockTag.getInteger(Constants.NBT.X_COORD), blockTag.getInteger(Constants.NBT.Y_COORD), blockTag.getInteger(Constants.NBT.Z_COORD));
conduitList.add(newPos);
}
}
@Override
@ -255,18 +114,6 @@ public class TileDemonCrucible extends TileInventory implements ITickable, IDemo
{
tag.setDouble("EnumWill" + entry.getKey().getName(), entry.getValue());
}
NBTTagList tags = new NBTTagList();
for (BlockPos pos : conduitList)
{
NBTTagCompound posTag = new NBTTagCompound();
posTag.setInteger(Constants.NBT.X_COORD, pos.getX());
posTag.setInteger(Constants.NBT.Y_COORD, pos.getY());
posTag.setInteger(Constants.NBT.Z_COORD, pos.getZ());
tags.appendTag(posTag);
}
tag.setTag(Constants.NBT.BLOCKPOS_CONNECTION, tags);
}
// IDemonWillConduit

View file

@ -0,0 +1,130 @@
package WayofTime.bloodmagic.tile;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import WayofTime.bloodmagic.api.soul.DemonWillHolder;
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
import WayofTime.bloodmagic.api.soul.IDemonWillConduit;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
public class TileDemonPylon extends TileEntity implements ITickable, IDemonWillConduit
{
public DemonWillHolder holder = new DemonWillHolder();
public final int maxWill = 100;
public final double drainRate = 1;
public TileDemonPylon()
{
}
@Override
public void update()
{
if (worldObj.isRemote)
{
return;
}
for (EnumDemonWillType type : EnumDemonWillType.values())
{
double currentAmount = WorldDemonWillHandler.getCurrentWill(worldObj, pos, type);
for (EnumFacing side : EnumFacing.HORIZONTALS)
{
BlockPos offsetPos = pos.offset(side, 16);
double sideAmount = WorldDemonWillHandler.getCurrentWill(worldObj, offsetPos, type);
if (sideAmount > currentAmount)
{
double drainAmount = Math.min((sideAmount - currentAmount) / 2, drainRate);
double drain = WorldDemonWillHandler.drainWill(worldObj, offsetPos, type, drainAmount, true);
WorldDemonWillHandler.fillWill(worldObj, pos, type, drain, true);
}
}
}
}
@Override
public void readFromNBT(NBTTagCompound tag)
{
super.readFromNBT(tag);
holder.readFromNBT(tag, "Will");
}
@Override
public void writeToNBT(NBTTagCompound tag)
{
super.writeToNBT(tag);
holder.writeToNBT(tag, "Will");
}
// 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

@ -13,10 +13,12 @@ import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
import WayofTime.bloodmagic.api.soul.IDemonWill;
import WayofTime.bloodmagic.api.soul.IDemonWillConduit;
import WayofTime.bloodmagic.api.soul.IDemonWillGem;
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
public class TileSoulForge extends TileInventory implements ITickable, IDemonWillConduit
{
public static final int ticksRequired = 100;
public static final double worldWillTransferRate = 1;
public static final int soulSlot = 4;
public static final int outputSlot = 5;
@ -49,12 +51,35 @@ public class TileSoulForge extends TileInventory implements ITickable, IDemonWil
@Override
public void update()
{
if (worldObj.isRemote)
{
return;
}
if (!hasSoulGemOrSoul())
{
burnTime = 0;
return;
}
for (EnumDemonWillType type : EnumDemonWillType.values())
{
double willInWorld = WorldDemonWillHandler.getCurrentWill(worldObj, pos, type);
double filled = Math.min(willInWorld, worldWillTransferRate);
if (filled > 0)
{
filled = this.fillDemonWill(type, filled, false);
filled = WorldDemonWillHandler.drainWill(worldObj, pos, type, filled, false);
if (filled > 0)
{
this.fillDemonWill(type, filled, true);
WorldDemonWillHandler.drainWill(worldObj, pos, type, filled, true);
}
}
}
double soulsInGem = getWill();
List<ItemStack> inputList = new ArrayList<ItemStack>();
@ -98,6 +123,7 @@ public class TileSoulForge extends TileInventory implements ITickable, IDemonWil
burnTime = 0;
}
}
}
public double getProgressForGui()