189 lines
4.3 KiB
Java
189 lines
4.3 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) {
|
|
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;
|
|
}
|
|
|
|
|
|
}
|