ModTweaker/src/api/java/thaumcraft/api/visnet/TileVisNode.java
2015-01-13 01:47:03 +02:00

189 lines
4.4 KiB
Java

package thaumcraft.api.visnet;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import thaumcraft.api.TileThaumcraft;
import thaumcraft.api.WorldCoordinates;
import thaumcraft.api.aspects.Aspect;
/**
* @author Azanor
*
* The tile entity used by nodes in the vis energy network. A node is either a source (like an aura node),
* a transport relay or vis receiver (like the infernal furnace).
*
*/
public abstract class TileVisNode extends TileThaumcraft {
WeakReference<TileVisNode> parent = null;
ArrayList<WeakReference<TileVisNode>> children = new ArrayList<WeakReference<TileVisNode>>();
/**
* @return the WorldCoordinates location of where this node is located
*/
public WorldCoordinates getLocation() {
return new WorldCoordinates(this);
}
/**
* @return the number of blocks away this node will check for parent nodes to connect to.
*/
public abstract int getRange();
/**
* @return true if this is the source or root node of the vis network.
*/
public abstract boolean isSource();
/**
* This method should never be called directly. Use VisNetHandler.drainVis() instead
* @param aspect what aspect to drain
* @param vis how much to drain
* @return how much was actually drained
*/
public int consumeVis(Aspect aspect, int vis) {
if (VisNetHandler.isNodeValid(getParent())) {
int out = getParent().get().consumeVis(aspect, vis);
if (out>0) {
triggerConsumeEffect(aspect);
}
return out;
}
return 0;
}
public void removeThisNode() {
for (WeakReference<TileVisNode> n:getChildren()) {
if (n!=null && n.get()!=null) {
n.get().removeThisNode();
}
}
children = new ArrayList<WeakReference<TileVisNode>>();
if (VisNetHandler.isNodeValid(this.getParent())) {
this.getParent().get().nodeRefresh=true;
}
this.setParent(null);
this.parentChanged();
if (this.isSource()) {
HashMap<WorldCoordinates, WeakReference<TileVisNode>> sourcelist = VisNetHandler.sources.get(worldObj.provider.dimensionId);
if (sourcelist==null) {
sourcelist = new HashMap<WorldCoordinates, WeakReference<TileVisNode>>();
}
sourcelist.remove(getLocation());
VisNetHandler.sources.put( worldObj.provider.dimensionId, sourcelist );
}
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
@Override
public void invalidate() {
removeThisNode();
super.invalidate();
}
public void triggerConsumeEffect(Aspect aspect) { }
/**
* @return
*/
public WeakReference<TileVisNode> getParent() {
return parent;
}
/**
* @return
*/
public WeakReference<TileVisNode> getRootSource() {
return VisNetHandler.isNodeValid(getParent()) ?
getParent().get().getRootSource() : this.isSource() ?
new WeakReference(this) : null;
}
/**
* @param parent
*/
public void setParent(WeakReference<TileVisNode> parent) {
this.parent = parent;
}
/**
* @return
*/
public ArrayList<WeakReference<TileVisNode>> getChildren() {
return children;
}
@Override
public boolean canUpdate() {
return true;
}
protected int nodeCounter = 0;
private boolean nodeRegged = false;
public boolean nodeRefresh = false;
@Override
public void updateEntity() {
if (!worldObj.isRemote && ((nodeCounter++) % 40==0 || nodeRefresh)) {
//check for changes
if (!nodeRefresh && children.size()>0) {
for (WeakReference<TileVisNode> n:children) {
if (n==null || n.get()==null || !VisNetHandler.canNodeBeSeen(this, n.get())) {
nodeRefresh=true;
break;
}
}
}
//refresh linked nodes
if (nodeRefresh) {
for (WeakReference<TileVisNode> n:children) {
if (n.get()!=null) {
n.get().nodeRefresh=true;
}
}
children.clear();
parent=null;
}
//redo stuff
if (isSource() && !nodeRegged) {
VisNetHandler.addSource(getWorldObj(), this);
nodeRegged = true;
} else
if (!isSource() && !VisNetHandler.isNodeValid(getParent())) {
setParent(VisNetHandler.addNode(getWorldObj(), this));
nodeRefresh=true;
}
if (nodeRefresh) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
parentChanged();
}
nodeRefresh=false;
}
}
public void parentChanged() { }
/**
* @return the type of shard this is attuned to:
* none -1, air 0, fire 1, water 2, earth 3, order 4, entropy 5
* Should return -1 for most implementations
*/
public byte getAttunement() {
return -1;
}
}