A new feature for trunk: scriptable flight AI.
This provides an intermediate level between calling "
performAttack
" or "
performFlyToRangeFromDestination
" to let the core game code provide generic behaviour, and the other extreme of carefully repositioning and reorienting the ship every frame with a frame callback.
In the AI, you use the command "
performScriptedAI
" or "
performScriptedAttackAI
" to put the ship into scriptable flight AI mode. It will then remain in this behaviour mode until you switch it to a different mode in the AI, or an error occurs in the script. While in this mode, the
scriptedAI
function in the ship script is called each frame to determine the behaviour.
Code: Select all
this.scriptedAI = function(delta)
{
// delta = duration of frame. Often irrelevant unless you're doing
// ultra-high-precision turns, or want a manouevre to last a particular
// length of time
// calculations happen here
return flightParameters;
}
The function gets a virtual joystick to control the ship with, by returning an object with up to 5 properties. All properties are optional, though returning an object is not. The default is level flight, at zero speed, with the forward weapon selected. Numbers outside the allowed range will be corrected to the nearest allowed value.
stickRoll
: number between -ship.maxRoll and ship.maxRoll
stickPitch
: similarly for pitch
stickYaw
: and for yaw
desiredSpeed
: number at least 0. If this is above ship.maxSpeed, and the ship has usable injectors, it will use them.
chosenWeapon
: "FORWARD", "AFT", "PORT" or "STARBOARD"
The ship will then respond to the virtual joystick. If a large change is requested - say the ship is in level flight, and the virtual joystick is moved to maximum clockwise roll - then it will take some time for the ship to respond and accelerate to that roll rate: quite possibly more than one frame.
If the attack version of the AI is selected, and the ship's current target is in the sights of the selected weapon (and there is a weapon there, and it's ready to fire, etc.), the weapon will be fired.
For example:
Code: Select all
this.scriptedAI = function(delta)
{
return { stickPitch: -0.2;
desiredSpeed: this.ship.maxSpeed;
chosenWeapon: "PORT"; };
}
will make the ship perform a fairly wide loop, and in attack mode, firing its port laser if the target crosses its sights. Might be a decent evasive attack if the target is the size of a small moon...
This lets you make a ship fly in a way consistent with other ships, without having to mess around with quaternions and masses of validation that you're not suddenly flipping the ship over in a single frame. A good grasp of vectors (and dot products, if you want to line the ship up with anything) is still needed, though.
Since the function is called once per frame, it needs to be quick. This is not the place to mess around searching for entities and new targets, for instance. You do have time for a fair bit of vector maths, though.
There's no direct support for things like missiles, ECM, and other ship equipment, but you can of course call
ship.fireMissile()
or
ship.fireECM()
from within the
scriptedAI
function.
A quick commented example:
Orbital Patrol. This OXP adds a number of police ships to planetary orbit in the safer systems, and then uses a scripted AI to make them actually orbit the planet.