RocketX-9_01 Beta on RX Server

A SLV derived jets mod used mostly for CTF.
User avatar
SC]-[WARTZ_{HoF}
Site Admin
Posts: 346
Joined: Wed May 10, 2017 7:08 am

Re: RocketX-9 (WIP)

Post by SC]-[WARTZ_{HoF} » Mon Apr 20, 2020 8:54 pm

I have a new build for RX9 coming soon. Just working on the afterburner meshes and cleaning up the aircraft self intersecting faces. I'm estimating Thursday for testing.

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9 (WIP)

Post by Nelsona » Mon Apr 20, 2020 9:33 pm

I'm thinking now at another experiment until we might see what it's needed in RX.
I have an old remake version for XC Devs, that map called GardenOfDeath. I'm wondering what if I do paths at 1600+ UU distance... because I can connect them in real ONE-WAY direction and... I can control what Pawn units are supposed to roam there - I want to see minimal charge of reachSpecs in that monstrosity. Maybe that one can be turned into a RX map as well... because it's GIGANTIC... There I think I can do separate ground routes for Bots losing jets and those with jets... because manually paths handling even if it means a longer working time, it does EXACTLY desired connections... I'm just thinking...
Anyway tomorrow I have to work something outside but maybe next days we can get into RX testing grounds...
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9 (WIP)

Post by Nelsona » Sat Apr 25, 2020 8:47 pm

Regarding the RX games, when I talked about two navigation routes, terrestrial and aerial, they would look something like this, those who fell from the air have the terrestrial path, those with planes have another path without interfering with each other.
TheOne_AndTheTwo.PNG
TheOne_AndTheTwo.PNG (708.24 KiB) Viewed 2144 times
Demonstrating that technology for RX Bot Support is available.
The PathNode you see at the end of the lines may have another character, a "specialhandling" function that causes the flight to start or land when the creature's inventory allows it, or placed elsewhere at beginning of aerial route.
Exactly as the flag is for CTFGame, just as we can have a node addressing RX types just as JumpSpot addresses ImpactHammer. No Inventory - no flight.
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

User avatar
SC]-[WARTZ_{HoF}
Site Admin
Posts: 346
Joined: Wed May 10, 2017 7:08 am

Re: RocketX-9 (WIP)

Post by SC]-[WARTZ_{HoF} » Sun Apr 26, 2020 4:54 pm

How was the testing for this map? Finally got the RX9 working in-game. Here are a couple screenshots of the jets.
Shot0177.jpg
Shot0177.jpg (136.44 KiB) Viewed 2125 times
Shot0178.jpg
Shot0178.jpg (184.95 KiB) Viewed 2125 times

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9 (WIP)

Post by Nelsona » Mon Apr 27, 2020 1:25 pm

SC]-[WARTZ_{HoF} wrote:
Sun Apr 26, 2020 4:54 pm
How was the testing for this map?
Plain UT 436/440. Paths are working. Pawn attempts the shortest route to you, here also it depends on where is your location. They can use ground paths or fly paths. Monster capable to fly actually can go where wants, if this pawn can swim, technically nothing stops it to track paths unless a small spot blocks it.
I practiced a bit of paths cosmetics and fine tuning in two old maps "ported". Conclusion is that we can manipulate routes exactly as we want getting rid of borks not by "learn how to place nodes" or "new things in account", no... Do we want Bot to step here and not there ? Yes ? It will go where we say.

By example: that jump down in a bad angle making pawn to loop around wall:
InitialRoutes.PNG
InitialRoutes.PNG (1.57 MiB) Viewed 2109 times
After a manual work taking a few minutes I got these - including other spots without paths and making more simple routes with less reachSpecs - see differences
AdjustedRoutes.PNG
AdjustedRoutes.PNG (1.57 MiB) Viewed 2109 times
If you ask if they work, due to my low skill in handling battle, Adept Bots On-Line defeated me... MBots more exactly which have in such cases less movement prediction because they can switch routeCache[x] at random when is reachable having some chaotic movement.

The FootNote for double routes:
Because Both of them can be used, we have to setup party depending on our will. If we want to Fly as priority, we can move nodes from Ground Route in small zig-zags for making road LONGER. That will be an Alternate solution then. Of course we do need re-building these paths After setting up Distances in order to record data correctly in reachSpecs. Longer route is used only if shorter route is locked or conditions are not accomplished.
These conditions in RX games must be clarified. If Bot bCanFly=True will see air paths but it must be able to follow them. If Bot has no jet or jet is empty, perhaps bCanFly must be False. Jet here must have a clear code. Paths ? These are not a problem. Next Level of pathing doesn't exist in any tutorial but... we can have here some lessons if you want to help me... else reader will need an english to english translator...
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

User avatar
SC]-[WARTZ_{HoF}
Site Admin
Posts: 346
Joined: Wed May 10, 2017 7:08 am

Re: RocketX-9 (WIP)

Post by SC]-[WARTZ_{HoF} » Mon Apr 27, 2020 4:52 pm

These two classes will need to be altered I believe in the RX script for navigation purposes.

SkyNode.uc

Code: Select all

//=====================================================================
// RX9_01.
//      ""(§)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
}]
SkyNet.uc

Code: Select all

//=====================================================================
// RX9_01.
//      ""(§)FrÅgÊd(§)""
//               **Monarch**
//
//              555 ---===CrAzYBoNeS===--- 555
//			Boppolis_The_Dog
//
//
// Thank you Al McElrath for SLV2.
//=====================================================================
/** SkyNet. Spawned on the server to build the sky node network. Built
	slowly over time in latent code so we don't choke.
*/
class SkyNet extends SLInfo config (RX9_01);


// DATA
//

// When we started.
var float buildStamp;

// Set based on gametype in postBeginPlay().
var bool bCTF, bAss;

// Tag given to auto-spawned nodes.
var() name autotag;

// Used during auto-spawning.
var NavigationPoint autonp;
var SkyNode firstsn, autosn;
var int i;

/** Map type. 0 == no sky nodes. 1 == tagged path nodes. 2 == sky
	nodes.
*/
var int type;

var byte goalnum;
var Actor goals[16];
var SkyNode goalNodes[16];
var float maxGoalDist[16];
var int nodeSum;

var() float weldRadius;
var() float linkRadius;

// The angle between a launch node and the next one that is "launchable". See goodNode().
var() float goodAngle;

// Set when we've finished building.
var bool bBuilt;

// For visual debugging.
var() config bool bShowNodes;
var() config bool bShowLinks;

// So we can do debugging just for the sky net.
var() config bool bDebug;

var() bool bNoAutoWeightNodes;
var() float randomLinkAdjust;
var() int laps;

var Util u;


// METHODS
//

function postBeginPlay() {
	u = spawn(Class'Util', self);
	u.setDebugLevel(DL_Verbose);
	if (bDebug)
		u.setOutputLevel(DL_Verbose);

	if (!properGame()) {
		u.err("postBeginPlay(): Only usable in CTF or Assault. Destroying.");
		destroy();
	}

	if (bAss)
		// 16 possible fort standards.
		goalnum = Assault(level.game).numForts;
	else
		// Only 4 flags.
		goalnum = 4;

	setMapType();

	u.debug("postBeginPlay(): map type: " $ type);
}


function setMapType() {
	local SkyNode sn;
	local NavigationPoint np;

	foreach allActors(Class'SkyNode', sn) {
		type = 3;
		return;
	}

	foreach allActors(Class'NavigationPoint', np, 'SKYNODE') {
		type = 2;
		return;
	}

	// No SL support.
	type = 1;
}


/** Currently only works with CTF and Assault.
*/
function bool properGame() {
	if (level.game.isA('CTFGame'))
		bCTF = true;

	if (level.game.isA('Assault'))
		bAss = true;

	return (bCTF || bAss);
}


/** Pick a random goal. The Optional args are for excluding a specific
	goal. Not currently used.
*/
function byte randomGoal(optional bool bEx, optional byte exgoal) {
	local int i, pnum;
	local int poss[16];

	for (i = 0; i < goalnum; i++) {
		if (goals[i] != none && !(bEx && i == exgoal)) {
			poss[pnum] = i;
			pnum++;
		}
	}
	
	if (pnum > 0) {
		return poss[rand(pnum)];
	} else {
		u.err("randomGoal(): no possible goals!");
		return 0;
	}
}


/** Returns the first node near us that has a positive launch record.
*/
function SkyNode findLaunchNode(Bot b) {
	local int team;
	local SkyNode sn, ln;
	local byte goal;
	local float cw, w;

	// Init.
	goal = -1;

	// If we are close to where we want to be, don't launch!
	if (getGoal(b, goal)) {
		if (vsize(goalNodes[goal].location - b.location) < linkRadius * 2.0) {
			u.debug("findLaunchNode(): in range of goal");
			return none;
		}
	}

	// Find the heaviest, good node.
	foreach b.radiusActors(Class'SkyNode', sn, linkRadius) {
		if (sn.launchWeight() > 0.50) {
			// Don't use this one if we'll have to do a 180 once we reach it.
			if (goodNode(sn, b)) {
				if (goal == -1) {
					// No goal? Just use the first one.
					ln = sn;
					break;
				} else {
					cw = sn.getWeight(goal);

					if (ln == none) {
						ln = sn;
						w = cw;
					} else {
						if (cw > w) {
							ln = sn;
							w = cw;
						}
					}
				}
			}
		}
	}


	if (ln != none) {
		u.debug("findLaunchNode(): node: " $ u.sname(ln));
		return ln;
	} else {
		u.debug("findLaunchNode(): no good nodes");
		return none;
	}
}


/** This sets the goal index. We may set bEject, so this needs to
	happen just before we test for that in pilotBehavior(). Returns
	true if we have a valid goal.
*/
function bool getGoal(Bot bot, out byte goal) {
	local byte team;
	local FortStandard fort;
	local int i;

	team = bot.playerReplicationInfo.team;

	// Set our goal!
	if (bCTF) {
		// Are we carrying a flag?
		if (bot.playerReplicationInfo.hasFlag != none) {
			goal = team;

		} else {
			// Go for an enemy flag!
			//goal = randomGoal(true, team);
			goal = findEnemyFlagGoal(team);
		} 

	} else if (bAss) {
		fort = Assault(level.game).bestFort;
		if (fort != none) {
			if (FortStandard(goals[goal]) != fort) {
				// Find the new fort index.
				for (i = 0; i < goalnum; i++) {
					if (goals[i] == fort) {
						goal = i;
						break;
					}
				}
			}
		} else {
			u.err("setGoal(): No best fort. Ejecting.");
			return false;
		}
	}

	return true;
}


/** FIX this.
*/
function byte findEnemyFlagGoal(byte team) {
	local int i;

	for (i = 0; i < goalnum; i++) {
		if (i != team) { // && flagAtBase(i)) {
			return i;
		}
	}
}


/** Returns true if the flag is safe and sound.
*/
function bool flagAtBase(byte team) {
	return CTFReplicationInfo(level.game.gameReplicationInfo).flagList[team].bHome;
}


/** Return true if there is a node after n which is roughly in a
	continuous direction from the bot and not blocked.
*/
function bool goodNode(SkyNode n, Bot b) {
	local vector ton;

	if (n != none) {
		u.debug("goodNode(" $ u.sname(n) $ ", " $ u.sname(b) $ ")");

		ton = normal(n.location - b.location);

		for (i = 0; i < arrayCount(n.links); i++) {
			if (n.links[i] != none && fastTrace(n.links[i].location, n.location) && (ton dot normal(n.location - n.links[i].location)) > goodAngle) {
				return true;
			}
		}
	}

	return false;
}


function SkyNode closestNode(vector loc, float radius) {
	local SkyNode sn, closest;
	local float dist;

	foreach radiusActors(Class'SkyNode', sn, radius, loc) {
		if (closest == none || vsize(sn.location - closest.location) < dist)
			closest = sn;
	}

	return closest;
}


/** Build our sky network.
*/
auto state BuildSkyNet {


begin:
	u.debug("BuildSkyNet:begin: Building sky network.", DL_Normal);
	buildStamp = level.timeseconds;

	// Need to auto-spawn sky nodes?
	if (type == 1 || type == 2) {
		u.debug("BuildSkyNet:begin: Auto-spawning nodes.", DL_Normal);
		autonp = level.navigationPointList;
		while (autonp != none) {
			// Catch our CTF goals here.
			if (bCTF && autonp.isA('FlagBase'))
				goals[FlagBase(autonp).team] = autonp;

			// If type 2, only spawn nodes for tagged path nodes.
			if (type == 1 || (type == 2 && autosn.tag == 'SKYNODE')) {
				autosn = autoSkyNode(autonp, autosn);
				nodeSum++;
			}
			autonp = autonp.nextNavigationPoint;
			sleep(0.0);
		}

		// Keep track of the last (which will be first).
		firstsn = autosn;
		u.debug("BuildSkyNet:begin: firstsn: " $ u.sname(firstsn));

		u.debug("BuildSkyNet:begin: Rising sky nodes.", DL_Normal);
		autosn = firstsn;
		while (autosn != none) {
			autosn.setWeldLoc();
			riseSkyNode(autosn);
			autosn = autosn.nextSkyNode;
			sleep(0.0);
		}
	}

	// Assault goals done separately here. Copy them over.
	if (bAss) {
		for (i = 0; i < goalnum; i++) {
			goals[i] = Assault(level.game).fort[i];
		}
	}

linkNodes:
	u.debug("BuildSkyNet:linkNodes: Linking sky nodes.", DL_Normal);
	autosn = firstsn;
	while (autosn != none) {
		// Destroy it if it has no links.
		if (!autosn.linkUp(linkRadius)) {
			// Need to keep a first one.
			if (autosn == firstsn)
				firstsn = autosn.nextSkyNode;

			autosn.destroy();
		}
	
		autosn = autosn.nextSkyNode;
		sleep(0.0);
	}


weightNodes:
	// Weigh the links, depending on gametype.
	if (!bNoAutoWeightNodes) {
		u.debug("BuildSkyNet:weightNodes: Weighting sky nodes.", DL_Normal);

		// Assign goal nodes.
		for (i = 0; i < goalnum; i++) {
			if (goals[i] != none)
				goalNodes[i] = closestNode(goals[i].location, linkRadius);
				u.debug("BuildSkyNet:weightNodes: new goal node: " $ u.sname(goalNodes[i]) $ " for: " $ u.sname(goals[i]));
		}

		// Set the weight to the distance first.
		autosn = firstsn;
		while (autosn != none) {
			for (i = 0; i < goalnum; i++) {
				if (goalNodes[i] != none) {
					autosn.weight[i] = vsize(goalNodes[i].location - autosn.location);
					u.debug("BuildSkyNet:weightNodes: " $ u.sname(autosn) $ ": distance to goal node " $ i $ ": " $ autosn.weight[i]);
					if (autosn.weight[i] > maxGoalDist[i])
						maxGoalDist[i] = autosn.weight[i];
				}
			}

			sleep(0.0);
			autosn = autosn.nextSkyNode;
		}

		// Now divide by the max and subtract from 1.0 to get the weight.
		u.debug("BuildSkyNet:weightNodes: dividing distances: firstsn: " $ u.sname(firstsn));
		autosn = firstsn;
		while (autosn != none) {
			for (i = 0; i < goalnum; i++) {
				if (goalNodes[i] != none) {
					autosn.weight[i] = 1.0 - (autosn.weight[i] / maxGoalDist[i]);
					u.debug("BuildSkyNet:weightNodes: " $ u.sname(autosn) $ ": goal: " $ i $ " weight: " $ autosn.weight[i]);
				}
			}
			sleep(0.0);
			autosn = autosn.nextSkyNode;
		}
	}

	// End.

	u.debug("BuildSkyNet:begin: Built network in " $ u.sf(level.timeseconds - buildStamp) $ " seconds.", DL_Normal);
	bBuilt = true;

} // End BuildSkyNet.


function SkyNode autoSkyNode(NavigationPoint np, SkyNode lastsn) {
	local SkyNode n;

	// Don't weld goal nodes.
	if (!isGoalNavPoint(np)) {
		foreach np.radiusActors(Class'SkyNode', n, weldRadius) {
			u.debug("autoSkyNode(): welded " $ u.sname(np) $ " to " $ u.sname(n));
			n.weld(np.location);
			// Return the last one, for setting firstsn.
			return lastsn;
		}
	}

	n = spawn(Class'SkyNode',, 'AutoSkyNode', np.location);

	if (n == none) {
		u.err("autoSkyNode(): spawn failed for " $ u.sname(np));
		return lastsn;
	}

	if (bShowNodes)
		n.bHidden = false;

	n.navPoint = np;
	n.nextSkyNode = lastsn;
	if (lastsn != none)
		lastsn.prevSkyNode = n;

	u.debug("autoSkyNode(): new skynode for " $ u.sname(np));

	return n;
}


function bool isGoalNavPoint(NavigationPoint np) {
	return ((bASS && np.isA('FortStandard')) || (bCTF && np.isA('FlagBase')));
}


function linkNodes() {
	local SkyNode last, n;

	foreach allActors(Class'SkyNode', n) {
		n.nextSkyNode = last;
		last = n;
	}
}		


function riseSkyNode(SkyNode n) {
	local vector down, up;

	// Don't rise goal nodes.
	if (!isGoalNavPoint(n.navPoint)) {
		down = roof(n.navPoint, -500);
		up = roof(n.navPoint, 500);

		n.setLocation(down + (up - down) * 0.5);
	}
}


function vector roof(Actor a, float dist) {
	local Actor hit;
	local vector end, hl, hn;

	end = a.location + vect(0, 0, 1) * dist;
	hit = a.trace(hl, hn, end, a.location, false);
	if (hit != none)
		return hl;
	else
		return end;
}



// end

defaultproperties
{
     autotag=autoSkyNode
     weldRadius=300.000000
     linkRadius=1800.000000
     goodAngle=0.200000
     randomLinkAdjust=0.050000
}

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9 (WIP)

Post by Nelsona » Tue Apr 28, 2020 7:28 pm

Has anyone saw these working ? Different said, do these working in some map with some mod or are just fantasies ?

Let me see: I tested Bots in two above maps posted and... those two lab mods which I posted with fly bot and CTF tracker - WORKED in those maps pathed.
For me solution would be simple stuff:
- NextNode doesn't have ground under it at 80 UU - max reachable point for ground pawn.

If (NavigationPoint(MoveTarget) != None)
NPoint(MoveTarget).DescribeSpec(NPoint(MoveTarget.UpstreamPaths0-15,Start,End,reachflags,distance)
if (reachFlags == 2)
Seeker.bAltfire - launch jet somehow
Seeker.SetPhysics(PHYS_Flying) - MUST BE
Perhaps SetBase whatever - These moves needs tested... To much calculations when engine gives nothing are probably useless. Maps must be more simple as possible. Mappers have problems with generic lifts and we want more math ? I'm not sure if worth writing 2 pages of script in a NavigationPoint - engine will quit pointing way very quickly...
Else, if they are mapped in run-time won't have connections too soon. A map pathed in UGOLD with High located PathNodes Will gain R_FLY automatically, the rest is ENGINE.
Keep in mind that some maps have only aerial routes between bases passing over some LAVA - nothing is connecting these out of newer Editing assets.
UGold is helpful because allows us through a builder to do exactly what we want - and amazingly we can event test routes integrity from a FlagBase to the other FlagBase.
In primitive mapping format we can only have R_SWIM connections done before building final geometry out of Water - we must decide what we want and not a bunch of "foreach AllActors"... If Jet is setting up Bot to "PHYS_None" good bye navigation - ANY navigation, more or less aerial...

Alternate
Designing pawns "FBOT" for this AIR task - Monsters flying are an example using ALL kind of paths - Manta actually can even swim as well and fly and track ground nodes... and it moves everywhere... As far as I know bot might fly but... they forgot animations for that - see "fallingstate" from Bot.

Point Next:
Tell me a map which you want to have two routes: aerial and ground paths separate like in picture above.

Then... I would like to see all that JET thingy what does it do with Bot.
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9_01 Beta on RX Server

Post by Nelsona » Wed Apr 29, 2020 12:42 pm

If the problem with artificial intelligence in games with airplanes of all kinds cannot be solved due to the structure that UE1 has, at least we can adjust a little the "magic" of spam that they have of the "forced" solutions. For two years now, I have been making a mutator that addresses the interference between players positioned in the same place at the beginning of the game. We simply take a PathNode and if it has a "factory" TAG we bring a plane to that place -10 UU. Then in the four random directions we cause the appearance of fuel: -x x -y y. We then exchange this TAG with a custom RX09 to avoid other repeated occurrences. We are already considering what is accessible around the flag - I don't really see what we are doing in Assault, I think we are postponing it a bit there.

Collection also and the desire for them must be controlled, you saw how stupid it looks running in place without moving.

We make a check of their height related to the appearance of these items. We don't need what can't be collected at height without already having the plane in inventory, it doesn't make sense to need a plane to collect a plane. However, at this time I do not see codes on the desire for the item versus what we already have in the inventory. And then I have to write a few small things but with a major impact in the course of the action...

I'll address all of this later because I have something that has been frustrating me for a long time on "RangedAttack," something that doesn't take into account the weapon used and the ammunition, and so I'm not surprised by some stupid reactions from the machine-controlled creature. When I say creature, I'm talking about old classes as well that have EXACTLY the same code.

Bot.uc

Code: Select all

ReadyToAttack:
	DesiredRotation = Rotator(Target.Location - Location);
	PlayRangedAttack();
	if ( Weapon.bMeleeWeapon )
		GotoState('Attacking');
	Enable('AnimEnd');
Firing: //Firing here
	if ( Target == None )
		GotoState('Attacking');
	TurnToward(Target);
	Goto('Firing'); //GoTo Firing if target still there - target might don't do anything - like I did and it will exist and DispersionPistol exists - Jessus
Bots.uc

Code: Select all

ReadyToAttack:
	DesiredRotation = Rotator(Target.Location - Location);
	PlayRangedAttack();
	Enable('AnimEnd');
Firing:
	if ( Target == None )
		GotoState('Attacking');
	TurnToward(Target);
	Goto('Firing');
Turn and turn while weapon still fire. Timer should change things but some weapons might be crapped and then... Pawn stuck is a direct result.
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

Nelsona
Posts: 876
Joined: Sat Sep 30, 2017 5:03 am

Re: RocketX-9_01 Beta on RX Server

Post by Nelsona » Wed Apr 29, 2020 2:38 pm

RX assets proposals.

Code: Select all

class Konglauncher extends SLWeapon config (....
....
event float BotDesireability(Pawn Bot)
{
	local float desire;
	local bool bHaveJet;
	local Inventory Inv;

	for ( Inv=Bot.Inventory; Inv!=None; Inv=Inv.Inventory )
	{
		if ( Inv.IsA('Konglauncher') )
		{
			bHaveJet = True;
			if ( KongLauncher(Inv).AmmoType == None || (KongLauncher(Inv).AmmoType.AmmoAmount < 1 && !KongLauncher(Inv).bWeaponStay) )
				return 3;
			return -1;
		}
	}
	if ( !bHaveJet )
		return 3;
	else
		return -1;

	return Super.BotDesireability(Bot);
}
I gotta see what does it do..
Not often maintained
My UT Mapping works...
Learn the rules like a pro, so you can break them like an artist.
- Pablo Picasso -

User avatar
SC]-[WARTZ_{HoF}
Site Admin
Posts: 346
Joined: Wed May 10, 2017 7:08 am

Re: RocketX-9_01 Beta on RX Server

Post by SC]-[WARTZ_{HoF} » Wed Apr 29, 2020 2:43 pm

Whatever you think needs to be adjusted properly. Have at it. I'm just as curious. At the moment I'm trying to limit polycounts where I can. Ferali has enlightened me on some code he used for NW3.

Code: Select all

//Get framerate level: 0 = OK, -1=>-5 = Slowdown, 1=>5+ = Speedup
simulated static function int getFrameRateLevel(LevelInfo Lvl, float Delta, optional bool returnExcessLevel)
{
local float frameRate, minFPS;

    if (!Class'NWInfo'.default.enableGlobalSmartPerformance)
        return 0;

    frameRate = 1/(Delta * Lvl.TimeDilation);
    minFPS = Class'NWInfo'.default.smartPerformanceMinFPS;
    if (!returnExcessLevel && frameRate >= minFPS)
        return 0;
    return Int(frameRate / (minFPS / 5.0)) - 5;
}

//Get LODBias value based on current framerate
simulated static function float getFrameRateBasedLODBias(LevelInfo Lvl, float Delta, float curLODBias)
{
local int perfoEval;
    
    perfoEval = static.getFrameRateLevel(Lvl, Delta, True);
    if (perfoEval == 1)
        return curLODBias;
    return FClamp(curLODBias + static.getSign(perfoEval)*Delta*3, Class'NWInfo'.default.MinLODBias, Class'NWInfo'.default.MaxLODBias);
}
I'm gonna see if I need to apply this type of handling LOD Bias.

Post Reply