Page 1 of 3

(Release) Fast Target Selector

Posted: Mon Oct 24, 2016 9:03 am
by phkb
I've always found the standard targeting system in Oolite a bit fiddly, particularly if your target is on the edge of scanner range (and I'm not the only one!). You have to jiggle the crosshairs around over the target hoping that the ident system locks on (unless I've missed something somewhere - quite possible!). And the player is at a disadvantage here because it's not something that NPC's have to worry about - their targets are selected automatically as part of the AI routines.

There are a couple of OXP's out there that help with targeting. Thargoid's "Target Autolock Plus" auto-selects hostile targets if you don't have a target set. Timer's "Targeter" allows the player to switch modes between different target types, and then they can cycle through all available targets of that type, which does a similar job to CSOTB's "Military Targeting System" (an OXP which has sadly stalled at v1).

But I wanted something a bit simpler. I wanted two modes of operation - standard, and red alert - and I wanted the system to work out which mode it should be in on its own. Then I can just cycle through whatever targets are visible. This is not designed as a do-it-all-for-you type of thing. I just wanted something that would enable me to quickly find targets and highlight them on the scanner.

And so Fast Target Selector was born. I've been using this for quite a while now, and have refined the code over time as I've learnt more about Oolite JS, and I think it's pretty stable. It's dead easy to use. Prime with shift-N, then "n" cycles forward through available targets, and "b" cycles backwards. Wormholes are not targeted - you have to target them the traditional way. It's set up to use the "Fast Affinity Defensive" slot, so hopefully it will be engaged by default when you purchase the equipment. That means you just have to press "0" (zero) to switch to the next target no matter what other equipment you have primed.

The equipment only costs 10cr. I've kept the costs down to make it a viable purchase option for brand new Jamesons, to make their life a bit easier.

Download via the expansion pack manager, or you can download from the [EliteWiki] wiki

Comments, feedback and bug reports welcome!

Re: (Release) Fast Target Selector

Posted: Mon Oct 24, 2016 9:26 am
by Cody
phkb wrote:
You have to jiggle the crosshairs around over the target hoping that the ident system locks on (unless I've missed something somewhere...).
Yep, you've missed something... while jiggling the crosshairs, you gotta intone the magic word: Auummmm!

Re: (Release) Fast Target Selector

Posted: Mon Oct 24, 2016 9:40 am
by Diziet Sma
Cody wrote:
while jiggling the crosshairs, you gotta intone the magic word: Auummmm!
Huh.. and all this time, I've been using "c'mon you #@$%^& %&$$#@!"

Cool idea, phkb!

Re: (Release) Fast Target Selector

Posted: Mon Oct 24, 2016 9:05 pm
by phkb
Cody wrote:
Yep, you've missed something... while jiggling the crosshairs, you gotta intone the magic word: Auummmm!
I knew it!
Diziet Sma wrote:
all this time, I've been using "c'mon you #@$%^& %&$$#@!"
Yeah, I tried that one too. :)

Re: (Release) Fast Target Selector

Posted: Fri Jan 27, 2017 1:13 pm
by Astrobe
It looks like version 1.1 has a download problem: "Downloaded OXZ does not have the same identifer and version as expected. This might be due to your manifests list being out of date - try updating it."

Re: (Release) Fast Target Selector

Posted: Fri Jan 27, 2017 10:11 pm
by phkb
Sorry, forgot to actually update the version number. Should be fixed now.

Re: (Release) Fast Target Selector

Posted: Fri Feb 03, 2017 5:37 pm
by Astrobe
I'm afraid there's still something wrong. Perhaps upper/lower caps. Last time I had to update the manifest half a dozen times because of those silly details.

Re: (Release) Fast Target Selector

Posted: Fri Feb 03, 2017 9:20 pm
by phkb
Eek! A rookie mistake - zipped the pack at the wrong directory level. It should work now. My apologies for this mix up.

Re: (Release) Fast Target Selector

Posted: Wed Mar 22, 2017 12:30 am
by cag
I'm pretty new to oolite but a coder from the dark ages (pre-web) and got the itch to tinker. There's nothing wrong w/ FTS but I found it slow to respond sometimes; turns out I was loading too many oxp's. Before I figured that out, I optimized some of your code and got 15-40% faster, depending on how full my scanner was. I only just recently figured out how to benchmark it and on my rig, we're only talking a dozen or so msec. Rather than toss it, I figured every little bit helps, esp. on slower rigs, so here goes. I modified 2 variable declarations at the top and everything from lookForTarget() to eof:

Code: Select all

... line 23
this._index = -1;							// position of players selected target in array
//this._sortRequired = false;					// indicates whether the scan data array needs to be sorted
//cag: no longer used

... line 31
this._ignoreRoles = ["btd_dummy_entity"];	// ship roles that will be ignored (ie they won't be selected)
//cag: increasing the length of _ignoreRoles requires chg's to $findNPCShips()
this._active = false;						// flag to indicate the FTS is in operation

... line 221
this.$lookForTarget = function(direction) {
	
	var currNPC = null;
	var ps = player.ship;
	var valid = false;
	
	this.$refreshArray();

	if (this._npc && this._npc.length > 0) {
		var lc = 0;
		do {
			this._index += direction;					
			// select the next/previous index value, based on the direction
			if (this._index < 0) 						
				// if we get to the beginning of the array, go back to the end
				this._index = this._npc.length - 1;
			else if (this._index > this._npc.length - 1) 
				// if we get to the end of the array, go back to the beginning
				this._index = 0;
			currNPC = this._npc[this._index];
			valid = currNPC && currNPC.isValid === true && currNPC.isJamming === false 
			        && currNPC.isCloaked === false;
			if (valid && ps.position.distanceTo(currNPC) < 25600) {
				// if the item is valid, make it the player's target
				ps.target = currNPC;
				break;
			}
			lc += 1;
		} while ( valid && lc < this._npc.length ); 	
		// if we didn't get a target, keep looping until we do
	}

}

this.$refreshArray = function() {
	// get the array of ships
	if ((global.clock.adjustedSeconds - this._dataAge) > 1) { // limit to once/sec
		this._npc = this.$findNPCShips();

		this._dataAge = global.clock.adjustedSeconds;
	}
}

this.$findNPCShips = function() {
	function _isNPC(entity)	{
		var wF = worldScripts.FastTargetSelector;
		if( !entity.isShip ) return false;
		if( entity.isPlayer ) return false;
		if( entity.displayName === "Wreckage" ) return false;
		if (wF._trueCondition === 3 && wF._scanMode === 0) {
			// during red alert, only target thargoids, missiles and enemy ships
			if( entity.isThargoid === true && entity.isCargo === false ) return true;
			if( entity.target === player.ship && entity.hasHostileTarget ) return true;
			if( entity.isMine ) return true;
			if( entity.isWeapon ) return true;
			return false;
		} 
		if( entity.isVisualEffect ) return false ;
		if( entity.docked ) return false; 						//cag: to exclude ships on escortdeck
//		if( wF._ignoreRoles.indexOf(entity.primaryRole) === -1 ) return false;  // list has only 1 entry & indexOf is slow!
		if( entity.primaryRole === wF._ignoreRoles[0] ) return false;
		return true;
	}
	return system.filteredEntities(this, _isNPC, player.ship, 25600);
}
Basically, I did 3 things:
- moved the trap for wreckage up into _isNPC (removing that loop)
- removed sortArray, as filteredEntities' return is sorted if you give it a 3rd arg (which you did)
- re-wrote _isNPC to be explicit

That last one probably didn't do much speed wise but statements like your original return statements in _isNPC are like fingernails on a chalk board to me. I should point out that those were logically flawless and will execute as you intended, but...

<pompous lecturing commencing>
There's so much going on they're hard to debug. And an interpreter can 'optimize' them in unexpected ways, if you don't get the brackets just right. What happens is, if it sees either:
<expression is true> || ...
<expression is false> && ...
it quits processing and ignores the rest of the code in the brackets or statement, if not bounded by brackets.
If you inadvertently combine contradictory expressions, the rest of the expressions *never* get evaluated (been there, done that, wasted hours using a primitive debugger [I did say dark ages, didn't I?] ).
If they get long and/or convoluted, you can end up evaluating expressions unnecessarily, which becomes obvious when written explicitly. (This last one was not aimed at you but someone in the audience; no names).
Another perk of being explicit is you can easily play around to speed things up, just by reordering the (equivalent value) lines. E.g. if you hadn't tested for Thargoid's before regular hostiles, I'd have moved that line up, as I'll take any edge I can get when they swarm!
<lecture ends; humble apologies>

Re: (Release) Fast Target Selector

Posted: Wed Mar 22, 2017 12:54 am
by phkb
Thanks cag! I am really thankful you took the time to optimise my code. I spend a lot of time coding in silence, without any feedback about what's good or not. I learned the small part of JavaScript I know by writing these OXP's, so I've probably done quite a few things in less than optimal ways.

In any case, I should be able to test these optimisations later this afternoon and post an official update.

Re: (Release) Fast Target Selector

Posted: Fri Mar 24, 2017 12:45 am
by phkb
Apologies for the delay -- version 1.2 is now available with code optimisations courtesy of cag. Very much appreciated!

Re: (Release) Fast Target Selector

Posted: Mon Apr 03, 2017 2:11 am
by cag
Oops! I made aw widdle mithake. At the last minute I threw in the check for landed escort deck ships and should have tested more - sorry, no excuse.
I checked w/ Norby and he set me straight. Nobody's complained yet, so maybe an update isn't required - your call. All you need to correct my error is replace this.$findNPCShips with the following:

Code: Select all


this.$findNPCShips = function() { //cag: optimized for speed
	var wF = worldScripts.FastTargetSelector;
	var wE = worldScripts.escortdeck;
	var i = null;
	
	function _isNPC(entity)	{
		if( !entity.isShip ) return false;
		if( entity.isPlayer ) return false;
		if( entity.displayName === "Wreckage" ) return false;
		if (wF._trueCondition === 3 && wF._scanMode === 0) {
			// during red alert, only target thargoids, missiles and enemy ships
			if( entity.isThargoid === true && entity.isCargo === false ) return true;
			if( entity.target === player.ship && entity.hasHostileTarget ) return true;
			if( entity.isMine ) return true;
			if( entity.isWeapon ) return true;
			return false;
		} 
		if( entity.isVisualEffect ) return false;
		// thanks to Norby for this escortdeck exclusion code
		if( wE ) { //escortdeck oxp is present
			i = wE.$EscortDeckShip.indexOf(entity);
			if( i >= 0 && wE.$EscortDeckShipPos[i] ) //entity is on deck
				return false; //so exclude this entity from target list
		}
//		if( wF._ignoreRoles.indexOf(entity.primaryRole) === -1 ) return false;  // list has only 1 entry & indexOf is slow!
		if( entity.primaryRole === wF._ignoreRoles[0] ) return false; 			// restore prev. line if _ignoreRoles grows
		return true;
	}
	return system.filteredEntities(this, _isNPC, player.ship, 25600);
}

Sorry I screwed up.

Re: (Release) Fast Target Selector

Posted: Mon Apr 03, 2017 2:50 am
by phkb
No worries. I don't use Escort Deck myself, so I was never going to notice. I'll get an update out later today.

[Edit] And done. 1.3 is now available.

Re: (Release) Fast Target Selector

Posted: Mon Apr 03, 2017 10:23 am
by Getafix
cag wrote: Mon Apr 03, 2017 2:11 am
cag wrote:
Sorry I screwed up.
“Once you start down the dark path, forever will it dominate your destiny, consume you it will.”
– Yoda

Re: (Release) Fast Target Selector

Posted: Sat Jun 03, 2017 3:19 pm
by gizmo
Fast Target Selector changes the way how blips blink in the scanner when targeted.
Is it possible to restore the default blinking behaviour?