I want to add Priority AI scripts derived from Oolite Priority AI core scripts (such as oolite-missileAI.js) to Armoury OXP, which is licensed under CC-BY-NC-SA 3.0. Priority AI scripts are licensed under GPL v2 or later. CC-BY-NC-SA 3.0 and GPL v2 are incompatible.
with GPL v3 (which is "or later").
to 4.0, but the copyright holder(s) need to agree (Thargoid gave special permission in his adoption thread for anyone to take over his work and said that supersedes the license, which I think means that he is giving adopters of his work a proxy to act on his behalf with respect to the copyright, so I could in theory upgrade the license to CC-BY-NC-SA 4.0 in this particular case).
What is the community's view on this? Does including Priority AI scripts in OXPs mean that those OXPs must be released under GPL licenses? Can Priority AI be provided to OXP authors under a different, CC-BY-NC-SA 3.0 compatible license? Does transformative, creative, non-commercial, derivative use of Priority AI in the context of creating an expansion pack (which can be seen as a form of comment/criticism) represent
Code: Select all
// Armoury OXP Field Missile AI adapted from oolite-missileAI.js
// Licensed under CC-BY-NC-SA 3.0 with clauses - see readme
// Derived from a work licensed under GNU GPL v2 (or later) as indicated below.
/*
missileAI.js
Priority-based AI for missiles
Oolite
Copyright © 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
"use strict";
this.name = "Armoury Field Missile AI";
this.aiStarted = function() {
var ai = new worldScripts["oolite-libPriorityAI"].PriorityAIController(this.ship);
/* This is probably too effective for standard missile AI, but
* might be worth setting separately on ships that use missile
* swarms as their main weapon. It makes the missiles avoid each
* other a bit, so that the detonation of the first missile won't
* destroy the remainder. */
// ai.setParameter("oolite_flag_autoSpreadMissiles",true);
/* Launch correction when fired at target in aft arc */
if (this.ship.target && this.ship.target.position.subtract(this.ship.position).direction().dot(this.ship.vectorForward) < -0.8)
{
this.oolite_priorityai.setParameter("oolite_flag_launchAdjustMissile",true);
}
// prevent deceleration on launch
this.ship.desiredSpeed = this.ship.maxSpeed;
ai.setPriorities([
{
condition: ai.conditionMissileOutOfFuel, // The missile has traveled beyond the maximum missile range. The default is 30km, but this may be overridden by the oolite_missile_range parameter in shipdata script info.
behaviour: ai.behaviourMissileSelfDestruct // Destroys the missile without detonating the payload.
},
{
preconfiguration: ai.configurationCheckScanner, // Scans the missile's scanner range, placing a list of detected targets into the "oolite_scanResults" parameter. This is generally called in a preconfiguration before the first use of a conditionScannerContains... condition in the priority list. If the scanner is particularly full, the list will not contain all visible objects. The current scan limit is 16.
condition: ai.conditionScannerContainsUnspreadMissile, // The scan contains a missile which has the same target and owner as this missile, but is closer to the target and within 500 metres of this missile. This is mainly used for "smart" missiles to ensure that impact times for a salvo are spread out.
configuration: ai.configurationMissileAdjustSpread, // This function sets an intermediate destination for "smart" missiles which are adjusting their flight path to spread out a salvo's impacts on target.
// This configuration sets a destination, a desired range and a desired speed suitable for use with behaviourApproachDestination. Unless otherwise stated, cruiseSpeed (80%) will be used as the desired speed.
behaviour: ai.behaviourApproachDestination, // Travels from the current position to within desiredRange of destination, avoiding obstacles on the way.
reconsider: 2
},
{
condition: ai.conditionMissileNeedsLaunchEvasion, // This function checks if the oolite_flag_launchAdjustMissile parameter is set to a non-null value, and returns true if so.
configuration: ai.configurationMissileAdjustLaunch, // This function causes the missile to dive sharply. The intended use is in conjunction with conditionMissileNeedsLaunchEvasion to avoid collisions with the launching ship.
// This configuration sets a destination, a desired range and a desired speed suitable for use with behaviourApproachDestination. Unless otherwise stated, cruiseSpeed (80%) will be used as the desired speed.
behaviour: ai.behaviourApproachDestination, // Travels from the current position to within desiredRange of destination, avoiding obstacles on the way.
reconsider: 2
},
{
condition: ai.conditionHasTarget, // The missile's target is not null.
behaviour: ai.behaviourMissileInterceptTarget, // Close to the desired missile range (default 25m, or specified by the oolite_missile_proximity key in script info), detonating when reached.
reconsider: 5
},
/* If target cloaks, go to last known location */
{
condition: ai.conditionHasInterceptCoordinates, // The missile has intercept coordinates set in the parameter "oolite_interceptCoordinates". These are used by missiles to home in on a last-known location if the target cloaks.
behaviour: ai.behaviourMissileInterceptCoordinates, // Close to the desired missile range (default 25m, or specified by the oolite_missile_proximity key in script info), detonating when reached. The coordinates to close in on are specified in the "oolite_interceptCoordinates". This is used to track missile targets which cloak.
reconsider: 1
},
/* Target lost. Self-destruct */
{
behaviour: ai.behaviourMissileSelfDestruct // Destroys the missile without detonating the payload.
}
]);
}
/* ECM response function, which must be set in shipdata script_info as oolite_missile_ecmResponse = "_ecmMissileResponse"; */
this._ecmMissileResponse = function()
{
switch (1 + Math.floor(Math.random() * 20)) // roll d20 (1 - 20)
{
case 1: // 5% chance spawn mines around target position (or around missile location, if target lost) and detonate missile
log("fieldMissile launched by " + this.ship.displayName + " responding to ECM by throwing mines around target and detonating");
this.ship.AIScript._dropMines();
this.ship.AIScript.shipAchievedDesiredRange(); // Detonate the missile and damage nearby ships (adjust with script_info oolite_missile_blastPower, oolite_missile_blastRadius, oolite_missile_blastShaping)
return;
case 2: // 5% chance brief tumble, then explode (no damage)
log("fieldMissile launched by " + this.ship.displayName + " responding to ECM by tumbling and exploding (no damage)");
this.oolite_priorityai.behaviourTumble(); // Start tumbling. Unlike most behaviours, this one does not include the standard responses, so you will need to manually request a reconsideration of priorities if one is needed.
this.oolite_priorityai.setPriorities([ // replace the priorities list from aiStarted with new priorities: self-destruct only
/* Self-destruct. */
{
behaviour: ai.behaviourMissileSelfDestruct // Destroys the missile without detonating the payload.
}
], 0.25 + Math.random() * 1.50); // delay for 0.25 to (almost) 1.50 seconds [setPriorities implicitly triggers a reconsideration of priorities]
return;
case 3: // 5% chance scatter mines around missile location, brief tumble, then explode (no damage)
log("fieldMissile launched by " + this.ship.displayName + " responding to ECM by scattering mines, tumbling and exploding (no damage)");
this.ship.AIScript._scatterMines();
this.oolite_priorityai.behaviourTumble(); // Start tumbling. Unlike most behaviours, this one does not include the standard responses, so you will need to manually request a reconsideration of priorities if one is needed.
this.oolite_priorityai.setPriorities([ // replace the priorities list from aiStarted with new priorities: self-destruct only
/* Self-destruct. */
{
behaviour: ai.behaviourMissileSelfDestruct // Destroys the missile without detonating the payload.
}
], 0.25 + Math.random() * 1.50); // delay for 0.25 to (almost) 1.50 seconds [setPriorities implicitly triggers a reconsideration of priorities]
return;
default: // 85% chance no effect
return;
}
}
this._dropMines = function () {
if (this.ship.target && this.ship.target.isValid && this.ship.position.distanceTo(this.ship.target.position) < 500) // if the missile has a valid target within 0.5km, spawn mines around the target
{
var mineCount = Math.ceil(Math.random() * 11) + 19; // 20-30 mines to be thrown around target position (250m radius)
system.addShips("armoury_fieldMine", mineCount, this.ship.target.position, 250);
}
else // otherwise just scatter mines wherever the missile is now
{
this._scatterMines();
}
}
this._scatterMines = function () {
var mineCount = Math.ceil(Math.random() * 11) + 19; // 20-30 mines to be thrown around missile position (250m radius)
system.addShips("armoury_fieldMine", mineCount, this.ship.position, 250);
}