//=====================================================================
// NemesisWINGSvX.
//      ""(§)FrÅgÊd(§)""
//               **Monarch**
//
//              555 ---===CrAzYBoNeS===--- 555
//			Boppolis_The_Dog
//
//
// Thank you Al McElrath for SLV2.
//=====================================================================
/** Nav point in the sky.
*/
class SkyNode extends NavigationPoint;


// DATA
//

var() float linkRadius;
var() float randomLinkAdjust;
var() float suggestedSpeed;
var() bool bOffensiveNode;

// Used in racing.
var() bool bGateNode;
var() bool bFinalNode;

var SkyNode links[5];
var float ldists[5];
var SkyNodeBeam beams[5];

var float weight[16];
var bool bWeighed;
var int weighDepth;

/** Keep track of launches so we can decide whether or not to try on
	this one again. We keep the same launch data for both teams. It's an
	anti-stupidity thing. Same for wall deathes, but not shots.
*/
var int launches;
var int launchSxs;

var int passes;				// No. of times somebody's passed us.
var int teamPasses[4];		// Same as above, but for teams.
var int wallDeaths;			// Times we've ran into a wall on this node.
var int shotDeaths[4];		// Times we've been shot down, per team.

var SkyNode nextSkyNode;
var SkyNode prevSkyNode;
var NavigationPoint navPoint;

// Track nodes we're welding to us, to avg. our position.
var vector weldLoc;
var int weldSum;

var Util u;


// METHODS
//

function postBeginPlay() {
	u = spawn(Class'Util', self);
}


function float getWeight(byte team) {
	return weight[team];
}


function weld(vector l) {
	weldSum++;
	weldLoc += l;
}


function setWeldLoc() {
	if (weldSum > 0) {
		setLocation((location + weldLoc) / (weldSum + 1.0));
	}
}


/** Gets called by the launcher at launch. If they reached their
	second node, they call us a success.
*/
function addLaunch(optional bool bSuccess) {
	if (bSuccess)
		launchSxs++;
	else
		launches++;
}


/** Returns the perc. of launch successes with this node. We give
	the node the benefit of the doubt if it hasn't been used yet.
*/
function float launchWeight() {
	return ((launchSxs + 1) / float(launches + 1));
}


function SkyNode randomLink() {
	local int i;

	i = rand(arrayCount(links));

	// The links may be none, but they're sorted.
	while (links[i] == none && i > 0)
		i--;

	u.debug("randomLink(): " $ u.sname(links[i]), DL_Verbose);
	return links[i];
}


/** Returns true on success. False if no links were created.
*/
function bool linkUp(float r) {
	local SkyNode sn;
	local int i;
	local float dist;
	local bool bNone;

	bNone = true;

	// Use mine if it's set.
	if (linkRadius > 0)
		r = linkRadius;

	foreach radiusActors(Class'SkyNode', sn, r) {
		if (sn != self && fastTrace(sn.location, location)) {
			dist = vsize(location - sn.location);
		
			bNone = false;

			for (i = 0; i < arrayCount(links); i++) {
				if (dist < ldists[i] || ldists[i] == 0) {
					insertLink(i, sn, dist);
					break;
				}
			}
		}
	}

	return !bNone;
}


/** Used for debugging.
*/
function showBeams(int goal) {
	local int i;
	local SkyNodeBeam beam;
	local float w, hi, lo;

	for (i = 0; i < arrayCount(links); i++) {
		if (beams[i] == none) {
			w = links[i].weight[goal];

			if (i == 0) {
				hi = w;
				lo = w;
			} else if (w < lo) {
				lo = w;
			} else if (w > hi) {
				hi = w;
			}

			beams[i] = spawn(Class'SkyNodeBeam',,,location, rotator(links[i].location - location));
			beams[i].drawScale = ldists[i] / 100.0;
		}
	}

	for (i = 0; i < arrayCount(links); i++) {
		if (beams[i] != none) {
			beams[i].ambientGlow = 255 * ((links[i].weight[goal] - lo) / (hi - lo));
			beams[i].scaleGlow = beams[i].ambientGlow;
			beams[i].lightBrightness = beams[i].ambientGlow;
		}
	}
}


/** Used for debugging.
*/
function hideBeams() {
	local int i;

	for (i = 0; i < arrayCount(links); i++) {
		if (beams[i] != none)
			beams[i].destroy();
	}
}


function insertLink(int index, SkyNode n, float dist) {
	local int i;

	for (i = arrayCount(links) - 2; i >= index; i--) {
		if (links[i] != none) {
			links[i + 1] = links[i];
			ldists[i + 1] = ldists[i];
		}
	}

	links[index] = n;
	ldists[index] = dist;
}


function vis(bool on, optional int goal) {
	if (!on)
		hideBeams();
	else
		showBeams(goal);
}


function destroyed() {
	u.debug("destroyed()", DL_Verbose);

	if (prevSkyNode != none)
		prevSkyNode.nextSkyNode = nextSkyNode;
}



// end

defaultproperties
{
     suggestedSpeed=-1.000000
     bStatic=False
     Style=STY_Translucent
     Texture=Texture'SLV2Textures.muzf.Spark'
     bCollideActors=True
}
