How to check an entity's altitude?

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

How to check an entity's altitude?

Post by UK_Eliter »

Dear all

I'm updating Thargoid's HiredGuns OXP (with his permission). One thing that needs changing is the tendency of the escorts (the 'hired guns') to crash into planetary bodies.

Now, I am having trouble determining how close they are to such bodies.

True, there are various messages Oolite gives to AIs about distances from such bodies. Yet, all such messages are issued, only, when the ship entity in question enters or leaves a sphere the extent of which is 3 x the radius of the planetary object. What I need, though, is a way of checking for being, I don't know, 5000 km from the planetary object - which is some three times less than that. Checking distance from each celestial object in the system does not seem like the way to go. entity and ship seem to lack an altitude property.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

The player.ship entity has an altitude calculation, which isn't exposed to JS at the moment. It finds the closest stellar body and performs the altitude calculation. Theoretically this calc could be applied to any ship, but it would need core code changes to provide the facility. I might have a look at how hard that calc is to apply to a ship entity, but if I can, it would mean you'd be targeting Oolite 1.89/1.90 for the update. If you need something now, you'd have to do those calculations yourself.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

What I did notice is that the older plist AI methods have some messages you can respond to: AEGIS_CLOSE_TO_MAIN_PLANET, CLOSE_TO_PLANET, CLOSE_TO_MOON, and CLOSE_TO_SECONDARY_PLANET. I'm not sure if equivalent functions exist in the newer PriorityAI.
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

phkb: thanks for the reply.

Now . .

> What I did notice is that the older plist AI methods have some messages you can respond to: AEGIS_CLOSE_TO_MAIN_PLANET, CLOSE_TO_PLANET, CLOSE_TO_MOON, and CLOSE_TO_SECONDARY_PLANET. I'm not sure if equivalent functions exist in the newer PriorityAI.

I am using the old AI. The messages you mention were those that I myself mentioned above. For the reasons I gave, they do not seem suitable to my purpose. Do please advise if you can suggest anything. Otherwise, those hired guns are going to keep crashing (into planetary bodies - actually, they crash into space stations too, but that is a separate problem).
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

UK_Eliter wrote: Tue May 28, 2019 5:47 pm
The messages you mention were those that I myself mentioned above.
Ah, apologies.

Well, until I get the core code changes made, the only other solution is JS. Here's something I prepared earlier...

Code: Select all

this.$getAltitudeForShip = function $getAltitudeForShip(ship) {
    var result = this.$calcAltitudeForShip(ship);
    log(this.name, "alt = " + result.altitude);
    log(this.name, "body = " + result.body);
}

// calculate the minimum altitude of the given ship from all planetary bodies
// returns dictionary with "altitude" and "body" properties
this.$calcAltitudeForShip = function $calcAltitudeForShip(ship) {
    var ent = [];
    var smallest = -1;
    var closest = null;
    if (system.isInterstellarSpace === false && system.sun) ent.push(system.sun);
    ent = ent.concat(system.planets);
    for (var i = 0; i < ent.length; i++ ) { //find the smallest distance
        var alt = this.$altitudeOverPlanetaryBody(ent[i], ship);
        if (smallest === -1 || (alt != -1 && alt < smallest)) {smallest = alt; closest = ent[i];}
    }
    return {"altitude":smallest, body:closest};
}

// calculates the altitude of a ship over a specific planetary body
this.$altitudeOverPlanetaryBody = function $altitudeOverPlanetaryBody(body, ship) {
    var shippos = ship.position;
    if (!shippos) return -1;
    return shippos.distanceTo(body) - body.radius - ship.collisionRadius;
}
Executing the function $getAltitudeForShip, and passing the player.ship as a parameter, will demonstrate the functions.

Hopefully that makes sense and helps a bit. I've only done a quick shakedown test of this, so there might be some edge cases to test for.
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

Marvellous. I will use that code - in conjunction with the automatically generated AI messages. For, I'll do this. When a hiredGun receives a 'CLOSE_TO_<SOMETHING>' message, I'll start a timer that calls your js code and reacts to its findings; when a hiredGun receives an 'AWAY_FROM_<SOMETHING>' message, I'll stop the timer.

Here's a thing, though. Is there an AWAY_FROM_SECONDARY_PLANET message? This page does not say there is, but it does say there is a CLOSE_TO_SECONDARY_PLANET message.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

UK_Eliter wrote: Tue May 28, 2019 11:32 pm
Here's a thing, though. Is there an AWAY_FROM_SECONDARY_PLANET message?
There doesn't seem to be. Although, there's no AWAY_FROM_<any entity> either.

What happens, though, is that when you call the checkAegis AI function, you'll get either one of the following:
AEGIS_CLOSE_TO_MAIN_PLANET
CLOSE_TO_SUN
CLOSE_TO_PLANET
CLOSE_TO_MOON
CLOSE_TO_SECONDARY_PLANET
AEGIS_IN_DOCKING_RANGE or
AEGIS_NONE which I think would mean, for you, that the ship was out of range.

But these messages are only sent if the checkAegis AI function is called. You are calling that function, right?
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

Hmm! I have not yet tested - I've only just finished the first draft of my code - but:
The aegis check is part of the system update and messages needs no command to generate them. The following messages are only generated when the status changes.

"AEGIS_CLOSE_TO_PLANET": Within 3x planetary radius of the main planet and not near station.
"AEGIS_IN_DOCKING_RANGE": Within 2x scanner radius of system station.
"AEGIS_LEAVING_DOCKING_RANGE": Has been in docking range but now only close to planet.
"AEGIS_NONE": None of the above three messages is true.
"AEGIS_CLOSE_TO_MAIN_PLANET": Within 3x planetary radius of the main planet and not near station.
"CLOSE_TO_PLANET": Within 3x planetary radius of any planet and not near station.
"AWAY_FROM_PLANET": Leaving the area of 3x planetary radius of any planet.
"CLOSE_TO_SUN": Within 3x sun radius of the sun .
"AWAY_FROM_SUN Leaving the area of 3x sun radius of the sun.
"CLOSE_TO_SECONDARY_PLANET": Within 3x radius of a planet that is not the main-planet.
"CLOSE_TO_MOON": Within 3x radius of a moon (=planet without atmosphere).
I quote http://wiki.alioth.net/index.php/OXP_howto_AI.
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

Also, I've forgotten how to get AI state changes - using plist AIs - to get logged in the main Oolite log. The following, in a ship script, doesn't seem to do it (even though I have the debugOXZ installed).

Code: Select all

this.debug = true;
var consoleDebugMessages;
if ( this.debug === true ) {
	this.logging = true;
	consoleDebugMessages = true;
}
else {
	consoleDebugMessages = false; // This does need setting to something, even when debugging is off.
}
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

UK_Eliter wrote: Wed May 29, 2019 12:45 am
Ah! I should read more.

To get the AI messages reported to the log, turn on the ship.reportAIMessages

Code: Select all

this.shipSpawned = function () {
	this.ship.reportAIMessages = true;
}
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

Thanks, phkb!

One more (slightly involved) thing, if I may. I'm making progress, but I'd like the calcAltitudeForShip function to return, additionally, a boolean that is true if and only the player is moving towards the nearest celestial body. To that, I imagine we'd need to check the ship's speed (it should be >0) but also its vector. It's the vector check I don't know how to do. Could you - or someone else - advise on that, please?
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

Something like this?

Code: Select all

this.$calcAltitudeForShip = function $calcAltitudeForShip(ship) {
    var ent = [];
    var smallest = -1;
    var closest = null;
    if (system.isInterstellarSpace === false && system.sun) ent.push(system.sun);
    ent = ent.concat(system.planets);
    for (var i = 0; i < ent.length; i++ ) { //find the smallest distance
        var alt = this.$altitudeOverPlanetaryBody(ent[i], ship);
        if (smallest === -1 || (alt != -1 && alt < smallest)) {smallest = alt; closest = ent[i];}
    }
    var deviation = 1;
    if (closest) deviation = ship.vectorForward.angleTo(closest.position.subtract(ship.position));
    return {"altitude":smallest, body:closest, movingTowards:((deviation < 0.18) && ship.speed > 0)};
}
Adjust the 0.18 value down to be ever more accurate about whether the ship is pointing at the closest planet. I took the 0.18 value from the Manual Witchspace Alignment OXP, so it might need some tweaking when dealing with planets.
UK_Eliter
---- E L I T E ----
---- E L I T E ----
Posts: 1246
Joined: Sat Sep 12, 2009 11:58 pm
Location: Essex (mainly industrial and occasionally anarchic)

Re: How to check an entity's altitude?

Post by UK_Eliter »

phkb,

Yes indeed! That's the stuff! The magic of Oolite and Javascript!

I now have the escorts recognising - without too much system load - when they are close to celestial bodies, messaging the player about it, and sometimes temporarily refusing to go further. The next and - for the moment, last - thing I'd like to implement is a flee function, whereby the escorts flee perpendicularly away from the celestial object (and I'm doing all this in a mix of JS and AI).
Rustem
Deadly
Deadly
Posts: 170
Joined: Mon May 25, 2015 5:23 pm
Location: Russia

Re: How to check an entity's altitude?

Post by Rustem »

... flee perpendicularly away from the celestial object ...
For AI.plist is simple solution:

Code: Select all

FLEEING = ("sendScriptMessage: setTargetToCelestialObject", "setStateTo: FLEE");
its help?

More complex (like in the sunSkimExitAI.plist or in the DSR_skimmer_courierAI.plist):

Code: Select all

ENTER = ("sendScriptMessage: setPerpendicularlyCoordinatesToCelestialObject", setDestinationFromCoordinates, "setDesiredRangeTo: 250", "setSpeedFactorTo: 2.0", performFlyToRangeFromDestination);
setTargetToCelestialObject, setPerpendicularlyCoordinatesToCelestialObject - calc by ship script.

P.S.

I solved similar task in the Stealth Raiders OXP[WIP] for sun skimmers (by AI.plist) and for ship combats in nearby sun (by priority-based Javascript AI was developed a final AI.js).

But I decided that the priority-based Javascript AI would be better. I developed and test the some prototypes for priority-based Javascript AI for flee from sun heat in combat.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4814
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: How to check an entity's altitude?

Post by phkb »

@rustem, both setTargetToCelestialObject and setPerpendicularlyCoordinatesToCelestialObject appear to be ship script functions, but without seeing the script it's hard to know what they do on their own. Which AI files are they from, and in which OXP?
Post Reply