Page 1 of 2
How to check an entity's altitude?
Posted: Sun May 26, 2019 7:41 pm
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.
Re: How to check an entity's altitude?
Posted: Mon May 27, 2019 12:18 am
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.
Re: How to check an entity's altitude?
Posted: Mon May 27, 2019 12:36 am
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.
Re: How to check an entity's altitude?
Posted: Tue May 28, 2019 5:47 pm
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).
Re: How to check an entity's altitude?
Posted: Tue May 28, 2019 10:36 pm
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.
Re: How to check an entity's altitude?
Posted: Tue May 28, 2019 11:32 pm
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.
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 12:35 am
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?
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 12:45 am
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.
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 1:57 am
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.
}
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 3:30 am
by phkb
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;
}
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 1:31 pm
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?
Re: How to check an entity's altitude?
Posted: Wed May 29, 2019 10:08 pm
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.
Re: How to check an entity's altitude?
Posted: Thu May 30, 2019 9:22 pm
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).
Re: How to check an entity's altitude?
Posted: Fri May 31, 2019 9:30 am
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.
Re: How to check an entity's altitude?
Posted: Fri May 31, 2019 11:19 am
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?