use of am2.api.power.PowerTypes in project ArsMagica2 by Mithion.
the class PowerNodeRegistry method getAllNearbyNodes.
/**
* Returns all power nodes within POWER_SEARCH_RADIUS
*
* @param location The center point to search from
* @param power The power type that the provider needs to supply or accept to be considered valid
* @return An array of IPowerNodes
*/
public IPowerNode[] getAllNearbyNodes(World world, AMVector3 location, PowerTypes power) {
//get the list of chunks we'll need to search in
ChunkCoordIntPair[] search = getSearchChunks(location);
//build the list of nodes from that chunk
HashMap<AMVector3, PowerNodeEntry> nodesToSearch = new HashMap<AMVector3, PowerNodeEntry>();
for (ChunkCoordIntPair pair : search) {
HashMap<AMVector3, PowerNodeEntry> nodesInChunk = powerNodes.get(pair);
if (nodesInChunk != null) {
//Add only vectors that are less than or equal to POWER_SEARCH_RADIUS_SQ away
for (AMVector3 vector : nodesInChunk.keySet()) {
if (location.distanceSqTo(vector) <= POWER_SEARCH_RADIUS_SQ && !vector.equals(location)) {
nodesToSearch.put(vector, nodesInChunk.get(vector));
}
}
}
}
//spin through and create our list of providers
ArrayList<IPowerNode> nodes = new ArrayList<IPowerNode>();
int deadNodesRemoved = 0;
for (AMVector3 vector : nodesToSearch.keySet()) {
if (!world.checkChunksExist((int) vector.x, (int) vector.y, (int) vector.z, (int) vector.x, (int) vector.y, (int) vector.z)) {
continue;
}
Chunk chunk = world.getChunkFromBlockCoords((int) vector.x, (int) vector.z);
if (!chunk.isChunkLoaded)
continue;
TileEntity te = world.getTileEntity((int) vector.x, (int) vector.y, (int) vector.z);
if (te == null || !(te instanceof IPowerNode)) {
//opportune time to remove dead power nodes
removePowerNode(chunk.getChunkCoordIntPair(), vector);
deadNodesRemoved++;
continue;
}
IPowerNode node = (IPowerNode) te;
nodes.add(node);
}
if (deadNodesRemoved > 0)
LogHelper.trace("Removed %d dead power nodes", deadNodesRemoved);
IPowerNode[] nodeArray = nodes.toArray(new IPowerNode[nodes.size()]);
LogHelper.trace("Located %d nearby power providers", nodeArray.length);
return nodeArray;
}
use of am2.api.power.PowerTypes in project ArsMagica2 by Mithion.
the class PowerNodeRegistry method tryPairNodes.
/**
* Attempts to pair the source and destination nodes by either a direct link or by going through conduits.
*
* @param powerSource The power source
* @param destination The destination point
* @return A localized message to return to the entity attempting to pair the nodes, either of success or why it failed.
*/
public String tryPairNodes(IPowerNode powerSource, IPowerNode destination) {
if (powerSource == destination) {
return StatCollector.translateToLocal("am2.tooltip.nodePairToSelf");
}
//Can the power source provide any of the valid power types for the destination?
ArrayList<PowerTypes> typesProvided = new ArrayList<PowerTypes>();
for (PowerTypes type : destination.getValidPowerTypes()) {
if (powerSource.canProvidePower(type)) {
typesProvided.add(type);
}
}
if (typesProvided.size() == 0) {
//no valid power types can be provided
return StatCollector.translateToLocal("am2.tooltip.noSupportedPowertypes");
}
//set up vectors and calculate distance for pathing purposes
AMVector3 sourceLocation = new AMVector3((TileEntity) powerSource);
AMVector3 destLocation = new AMVector3((TileEntity) destination);
double rawDist = sourceLocation.distanceSqTo(destLocation);
if (rawDist > MAX_POWER_SEARCH_RADIUS) {
return StatCollector.translateToLocal("am2.tooltip.nodesTooFar");
}
//construct a list of all valid power types common between the source and destination
int successes = 0;
for (PowerTypes type : typesProvided) {
LinkedList<AMVector3> powerPath = new LinkedList<AMVector3>();
PowerNodePathfinder pathfinder = new PowerNodePathfinder(((TileEntity) powerSource).getWorldObj(), sourceLocation, destLocation, type);
List<AMVector3> path = pathfinder.compute(sourceLocation);
if (path == null)
continue;
for (AMVector3 vec : path) {
powerPath.addFirst(vec);
}
successes++;
getPowerNodeData(destination).registerNodePath(type, powerPath);
}
//are the nodes too far apart?
if (successes == 0) {
return StatCollector.translateToLocal("am2.tooltip.noPathFound");
}
if (successes == typesProvided.size())
return StatCollector.translateToLocal("am2.tooltip.success");
return StatCollector.translateToLocal("am2.tooltip.partialSuccess");
}
use of am2.api.power.PowerTypes in project ArsMagica2 by Mithion.
the class PowerNodeEntry method saveToNBT.
public NBTTagCompound saveToNBT() {
NBTTagCompound compound = new NBTTagCompound();
//power amounts
//list of entries containing power type IDs and the associated amount
NBTTagList powerAmountStore = new NBTTagList();
for (PowerTypes type : this.powerAmounts.keySet()) {
if (//sanity check
type == null)
continue;
//individual power type/amount entry
NBTTagCompound powerType = new NBTTagCompound();
//set power type ID
powerType.setInteger("powerType", type.ID());
//set power amount
powerType.setFloat("powerAmount", powerAmounts.get(type));
//attach the power node to the list
powerAmountStore.appendTag(powerType);
}
//append list to output compound
compound.setTag("powerAmounts", powerAmountStore);
//power paths
NBTTagList powerPathList = new NBTTagList();
for (PowerTypes type : nodePaths.keySet()) {
//This is the actual entry in the power path list
NBTTagCompound powerPathEntry = new NBTTagCompound();
ArrayList<LinkedList<AMVector3>> paths = nodePaths.get(type);
//This stores each path individually for a given power type
NBTTagList pathsForType = new NBTTagList();
for (LinkedList<AMVector3> path : paths) {
//This stores each individual node in the given path
NBTTagList pathNodes = new NBTTagList();
for (AMVector3 pathNode : path) {
//This stores one individual node in the given path
NBTTagCompound node = new NBTTagCompound();
pathNode.writeToNBT(node);
//Append individual node to path
pathNodes.appendTag(node);
}
//Append path to list of paths for the power type
pathsForType.appendTag(pathNodes);
}
//set the power type that this list of paths is for
powerPathEntry.setInteger("powerType", type.ID());
//append the list of paths to the entry in the power path list
powerPathEntry.setTag("nodePaths", pathsForType);
//AMCore.log.info("Saved %d node paths for %s etherium.", nodePaths.get(type).size(), type.name());
//append this entry in the power path list to the list of power path entries
powerPathList.appendTag(powerPathEntry);
}
//append the entire power path list to the saved compound
compound.setTag("powerPathList", powerPathList);
return compound;
}
use of am2.api.power.PowerTypes in project ArsMagica2 by Mithion.
the class PowerNodeEntry method requestPowerFrom.
private float requestPowerFrom(World world, LinkedList<AMVector3> path, PowerTypes type, float amount) {
if (!validatePath(world, path))
return 0f;
AMVector3 end = path.getLast();
TileEntity te = world.getTileEntity((int) end.x, (int) end.y, (int) end.z);
if (te != null && te instanceof IPowerNode) {
if (((IPowerNode) te).canProvidePower(type)) {
return PowerNodeRegistry.For(world).consumePower(((IPowerNode) te), type, amount);
}
}
return 0f;
}
use of am2.api.power.PowerTypes in project ArsMagica2 by Mithion.
the class AMClientEventHandler method renderPowerFloatingText.
private void renderPowerFloatingText(DrawBlockHighlightEvent event, TileEntity te) {
PowerNodeEntry data = AMCore.proxy.getTrackedData();
Block block = event.player.worldObj.getBlock(event.target.blockX, event.target.blockY, event.target.blockZ);
float yOff = 0.5f;
if (data != null) {
GL11.glPushAttrib(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
for (PowerTypes type : ((IPowerNode) te).getValidPowerTypes()) {
float pwr = data.getPower(type);
float pct = pwr / ((IPowerNode) te).getCapacity() * 100;
AMVector3 offset = new AMVector3(event.target.blockX + 0.5, event.target.blockY + 0.5, event.target.blockZ + 0.5).sub(new AMVector3((event.player.prevPosX - (event.player.prevPosX - event.player.posX) * event.partialTicks), (event.player.prevPosY - (event.player.prevPosY - event.player.posY) * event.partialTicks) + event.player.getEyeHeight(), (event.player.prevPosZ - (event.player.prevPosZ - event.player.posZ) * event.partialTicks)));
offset = offset.normalize();
if (event.target.blockY <= event.player.posY - 0.5) {
RenderUtilities.drawTextInWorldAtOffset(String.format("%s%.2f (%.2f%%)", type.chatColor(), pwr, pct), event.target.blockX - (event.player.prevPosX - (event.player.prevPosX - event.player.posX) * event.partialTicks) + 0.5f - offset.x, event.target.blockY + yOff - (event.player.prevPosY - (event.player.prevPosY - event.player.posY) * event.partialTicks) + block.getBlockBoundsMaxY() * 0.8f, event.target.blockZ - (event.player.prevPosZ - (event.player.prevPosZ - event.player.posZ) * event.partialTicks) + 0.5f - offset.z, 0xFFFFFF);
yOff += 0.12f;
} else {
RenderUtilities.drawTextInWorldAtOffset(String.format("%s%.2f (%.2f%%)", type.chatColor(), pwr, pct), event.target.blockX - (event.player.prevPosX - (event.player.prevPosX - event.player.posX) * event.partialTicks) + 0.5f - offset.x, event.target.blockY - yOff - (event.player.prevPosY - (event.player.prevPosY - event.player.posY) * event.partialTicks) - block.getBlockBoundsMaxY() * 0.2f, event.target.blockZ - (event.player.prevPosZ - (event.player.prevPosZ - event.player.posZ) * event.partialTicks) + 0.5f - offset.z, 0xFFFFFF);
yOff -= 0.12f;
}
}
GL11.glPopAttrib();
}
}
Aggregations