/// <summary> /// Do a single bubble-sort pass over the transfer list to favor needy towers /// Guaranteed to place the neediest tower at the end of the list /// </summary> private void PerformSortingPass() { if (_powerLinksOut.Count < 2) { return; } PowerLink powerLink = _powerLinksOut[0]; // Only run if two or more links exist. int maxSeen = _powerLinksOut[0]._target.MaxReceivableEnergy();; for (int x = 0; x < _powerLinksOut.Count - 1; x++) { int energy = _powerLinksOut[x + 1]._target.MaxReceivableEnergy(); // Equal amounts should always be swapped to avoid a single tower hogging a constant +1 if (energy <= maxSeen) { _powerLinksOut[x] = _powerLinksOut[x + 1]; _powerLinksOut[x + 1] = powerLink; // keep shifting the best so far towards the end of the list } else { powerLink = _powerLinksOut[x + 1]; maxSeen = energy; } } }
public static GameObject CreatePowerLink(PowerManager iSource, PowerManager iTarget) { GameObject obj = (GameObject)GameObject.Instantiate(Active.PowerLinkPrefab, iSource.gameObject.transform.position, Quaternion.identity); PowerLink powerLink = obj.GetComponent <PowerLink>(); powerLink.transform.parent = Active.PowerLinkContainer.transform; powerLink.Init(iSource, iTarget); iSource._powerLinksOut.Add(powerLink); iTarget._powerLinksIn.Add(powerLink); return(obj); }
private void TransferEnergy(PowerLink powerLink, int energyToTransfer) { powerLink._target._totalReceived += energyToTransfer; _totalSent += energyToTransfer; powerLink._target._energy += energyToTransfer; _energy -= energyToTransfer; powerLink.lastTransfer = energyToTransfer; powerLink.Redraw(); }
/// <summary> ///Transfer energy to other towers for this tick ///NOTE: Towers with lots of needed energy are placed towards the end of the ///destination list because any energy surplus due to capacitiy early in the list ///rolls-over to the later towers in the list. /// </summary> private void PushEnergy() { PerformSortingPass(); // e is Energy // n is Numbero f Transfers Out. // tt is PowerLink //dst is PowerLink Target. // te1 transfer Capacity of reciever // te2 is energy capcity of reciever. // de = energy to transfer. //transfer energy out //note: lastEnergy >= current energy because this tower hasn't transfered out yet this tick int energyAvailable = Math.Min(_prototype._transferRate, _lastEnergy); int transfersRemaining = _powerLinksOut.Count; for (int x = 0; x < _powerLinksOut.Count; x++) { PowerLink powerLink = _powerLinksOut[x]; //compute amount to send int energyToTransfer = energyAvailable / transfersRemaining; int targetTransferCap = powerLink._target.MaxReceivableTransfer(); int targetEnergyCap = powerLink._target.GetEnergyCap(); if (targetTransferCap < energyToTransfer || targetEnergyCap < energyToTransfer) { if (targetTransferCap < targetEnergyCap) { energyToTransfer = targetTransferCap; _numSlowedByTransferRate++; //print(targetTransferCap+" < "+targetEnergyCap+" "+numSlowedByTransferRate); } else { energyToTransfer = targetEnergyCap; } } TransferEnergy(powerLink, energyToTransfer); energyAvailable -= energyToTransfer; transfersRemaining -= 1; } }
// Wrapper letting you use the target instead of the link public bool RemoveLink(PowerManager iTarget) { PowerLink link = null; foreach (PowerLink powerLink in _powerLinksOut) { if (powerLink._target == iTarget) { link = powerLink; break; } } if (link != null) { RemoveLink(link); return(true); } else { return(false); } }
bool NodesInLine(GameObject upNode, PowerLink downNode) { return(AngleBetweenNodes(upNode.transform.position, downNode.transform.position) <= tolerance); }
public void RemoveLink(PowerLink iLink) { iLink.remove(); }
public void AddLink(PowerManager iTarget, bool longLink) { Vector3 sourcePosition = transform.position; Vector3 targetPosition = iTarget.transform.position; // Isn't self // Has Room // Target Has Room // Link doesn't already exist. // Asserts? Something like it anyway. If x, continue, else break and throw exception. if (this != iTarget) { // Can't link to yoruself if ((CanLinkOutLong() && longLink) || CanLinkOutShort()) { // Gotta have room for output link. if (iTarget.CanLinkIn()) { // And input link on the target if (_powerLinksOut.Find(x => x._target == iTarget) == null && _powerLinksIn.Find(x => x._source == iTarget) == null) { // Make sure it doesn't exist already. No duplicates. // Check range. if (PowerLink.isInRange(this, iTarget, longLink)) { // Always break long links out if you have a link out already. // Only one allowed. if (longLink) { // Long links remove all other links out, and long links in on the target. RemoveLinksOut(); iTarget.RemoveLongLinksIn(); EntityManager.CreatePowerLink(this, iTarget); } else { // short links cannot exist with long links, in or out. RemoveLongLinksOut(); iTarget.RemoveLongLinksIn(); EntityManager.CreatePowerLink(this, iTarget); } } else { EntityManager.CreateFloatingText(targetPosition, "Out of Range", 1.0f, Color.red); } } else { EntityManager.CreateFloatingText(targetPosition, "Already Linked", 1.0f, Color.red); } } else { EntityManager.CreateFloatingText(targetPosition, "Link Limit Reached", 1.0f, Color.red); } } else { EntityManager.CreateFloatingText(sourcePosition, "Link Limit Reached", 1.0f, Color.red); } } else { EntityManager.CreateFloatingText(sourcePosition, "Cannot Link to Self", 1.0f, Color.red); } }