2008-02-24 21:07:20 +00:00
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
oolite-global-prefix.js
|
|
|
|
|
|
|
|
|
|
This script is run before any other JavaScript script. It is used to implement
|
|
|
|
|
parts of the Oolite JavaScript environment in JavaScript.
|
|
|
|
|
|
|
|
|
|
Do not override this script! Its functionality is likely to change between
|
|
|
|
|
Oolite versions, and functionality may move between the Oolite application and
|
|
|
|
|
this script.
|
|
|
|
|
|
|
|
|
|
“special” is an object provided to the script (as a property) that allows
|
|
|
|
|
access to functions otherwise internal to Oolite. Currently, this means the
|
|
|
|
|
special.jsWarning() function, which writes a warning to the log and, if
|
|
|
|
|
applicable, the debug console.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Oolite
|
2012-12-31 09:00:28 +00:00
|
|
|
|
Copyright © 2004-2013 Giles C Williams and contributors
|
2008-02-24 21:07:20 +00:00
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2010-07-30 21:54:50 +00:00
|
|
|
|
/*jslint white: true, undef: true, eqeqeq: true, bitwise: false, regexp: true, newcap: true, immed: true */
|
|
|
|
|
/*global Entity, global, mission, player, Quaternion, Ship, special, system, Vector3D, SystemInfo, expandMissionText*/
|
2009-05-22 22:45:02 +00:00
|
|
|
|
|
|
|
|
|
|
2011-01-02 17:54:54 +00:00
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
2008-02-24 21:07:20 +00:00
|
|
|
|
this.name = "oolite-global-prefix";
|
|
|
|
|
this.author = "Jens Ayton";
|
2012-12-31 09:00:28 +00:00
|
|
|
|
this.copyright = "© 2009-2013 the Oolite team.";
|
2013-01-21 10:15:06 +00:00
|
|
|
|
this.version = "1.77.1";
|
2008-02-24 21:07:20 +00:00
|
|
|
|
|
|
|
|
|
|
2011-01-12 21:36:10 +00:00
|
|
|
|
(function (special) {
|
|
|
|
|
|
2011-01-12 14:29:55 +00:00
|
|
|
|
// Utility to define non-enumerable, non-configurable, permanent methods, to match the behaviour of native methods.
|
2011-01-12 21:36:10 +00:00
|
|
|
|
function defineMethod(object, name, implementation)
|
2011-01-06 19:09:01 +00:00
|
|
|
|
{
|
2011-01-12 14:29:55 +00:00
|
|
|
|
Object.defineProperty(object, name, { value: implementation, writable: false, configurable: false, enumerable: false });
|
2011-01-06 19:09:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-01-11 22:14:03 +00:00
|
|
|
|
/**** Miscellaneous utilities for public consumption ****
|
|
|
|
|
Note that these are documented as part of the scripting interface.
|
|
|
|
|
The fact that they’re currently in JavaScript is an implementation
|
|
|
|
|
detail and subject to change.
|
|
|
|
|
*/
|
2008-03-10 00:01:30 +00:00
|
|
|
|
|
|
|
|
|
// Ship.spawnOne(): like spawn(role, 1), but returns the ship rather than an array.
|
2011-01-20 19:52:01 +00:00
|
|
|
|
defineMethod(Ship.prototype, "spawnOne", function spawnOne(role)
|
2008-03-10 00:01:30 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
var result = this.spawn(role, 1);
|
|
|
|
|
return result ? result[0] : null;
|
2011-01-06 12:05:16 +00:00
|
|
|
|
});
|
2008-03-10 00:01:30 +00:00
|
|
|
|
|
|
|
|
|
|
2009-10-10 12:23:24 +00:00
|
|
|
|
// mission.addMessageTextKey(): load mission text from mission.plist and append to mission screen or info screen.
|
2011-01-20 19:52:01 +00:00
|
|
|
|
defineMethod(Mission.prototype, "addMessageTextKey", function addMessageTextKey(textKey)
|
2009-10-10 12:23:24 +00:00
|
|
|
|
{
|
2011-01-11 22:14:03 +00:00
|
|
|
|
this.addMessageText((textKey ? expandMissionText(textKey) : null));
|
2011-01-06 19:09:01 +00:00
|
|
|
|
});
|
2009-10-10 12:23:24 +00:00
|
|
|
|
|
|
|
|
|
|
2011-03-10 22:02:52 +00:00
|
|
|
|
/* SystemInfo systemsInRange(): return SystemInfos for all systems within a
|
2009-09-05 18:19:23 +00:00
|
|
|
|
certain distance.
|
|
|
|
|
*/
|
2011-02-20 20:09:30 +00:00
|
|
|
|
defineMethod(SystemInfo.prototype, "systemsInRange", function systemsInRange(range)
|
2009-09-05 18:19:23 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
if (range === undefined)
|
2010-06-13 16:00:30 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
range = 7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SystemInfo.filteredSystems(this, function (other)
|
|
|
|
|
{
|
2011-02-20 20:09:30 +00:00
|
|
|
|
return (other.systemID !== this.systemID) && (this.distanceToSystem(other) <= range);
|
2011-01-06 19:09:01 +00:00
|
|
|
|
});
|
2011-01-06 12:05:16 +00:00
|
|
|
|
});
|
2009-09-05 18:19:23 +00:00
|
|
|
|
|
|
|
|
|
|
2011-02-20 20:16:44 +00:00
|
|
|
|
/* Because of messy history, SystemInfo.systemsInRange() is an alias to
|
|
|
|
|
system.info.systemsInRange(). This usage is discouraged and now undocumented.
|
|
|
|
|
(It should have been deprecated for 1.75, but wasn't.)
|
|
|
|
|
*/
|
2011-02-20 20:09:30 +00:00
|
|
|
|
defineMethod(SystemInfo, "systemsInRange", function systemsInRange(range)
|
|
|
|
|
{
|
|
|
|
|
return system.info.systemsInRange(range);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-01-11 22:14:03 +00:00
|
|
|
|
/* system.scrambledPseudoRandomNumber(salt : Number (integer)) : Number
|
2010-06-26 15:46:26 +00:00
|
|
|
|
|
|
|
|
|
This function converts system.pseudoRandomNumber to an effectively
|
|
|
|
|
arbitrary different value that is also stable per system. Every combination
|
|
|
|
|
of system and salt produces a different number.
|
|
|
|
|
|
|
|
|
|
This should generally be used in preference to system.pseudoRandomNumber,
|
|
|
|
|
because multiple OXPs using system.pseudoRandomNumber to make the same kind
|
|
|
|
|
of decision will cause unwanted clustering. For example, if three different
|
|
|
|
|
OXPs add a station to a system when system.pseudoRandomNumber <= 0.25,
|
|
|
|
|
their stations will always appear in the same system. If they instead use
|
|
|
|
|
system.scrambledPseudoRandomNumber() with different salt values, there will
|
|
|
|
|
be no obvious correlation between the different stations’ distributions.
|
|
|
|
|
*/
|
2011-01-20 19:52:01 +00:00
|
|
|
|
defineMethod(System.prototype, "scrambledPseudoRandomNumber", function scrambledPseudoRandomNumber(salt)
|
2010-06-26 15:46:26 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
// Convert from float in [0..1) with 24 bits of precision to integer.
|
2011-01-11 22:14:03 +00:00
|
|
|
|
var n = Math.floor(this.pseudoRandomNumber * 16777216.0);
|
2011-01-06 19:09:01 +00:00
|
|
|
|
|
|
|
|
|
// Add salt to enable generation of different sequences.
|
|
|
|
|
n += salt;
|
|
|
|
|
|
|
|
|
|
// Scramble with basic LCG psuedo-random number generator.
|
|
|
|
|
n = (214013 * n + 2531011) & 0xFFFFFFFF;
|
|
|
|
|
n = (214013 * n + 2531011) & 0xFFFFFFFF;
|
|
|
|
|
n = (214013 * n + 2531011) & 0xFFFFFFFF;
|
|
|
|
|
|
|
|
|
|
// Convert from (effectively) 32-bit signed integer to float in [0..1).
|
|
|
|
|
return n / 4294967296.0 + 0.5;
|
2011-01-06 12:05:16 +00:00
|
|
|
|
});
|
2010-06-26 15:46:26 +00:00
|
|
|
|
|
|
|
|
|
|
2011-01-18 15:30:39 +00:00
|
|
|
|
/* worldScriptNames
|
|
|
|
|
|
|
|
|
|
List of names of world scripts.
|
|
|
|
|
*/
|
|
|
|
|
Object.defineProperty(global, "worldScriptNames",
|
|
|
|
|
{
|
|
|
|
|
enumerable: true,
|
|
|
|
|
get: function ()
|
|
|
|
|
{
|
|
|
|
|
return Object.keys(global.worldScripts);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 19:09:01 +00:00
|
|
|
|
/* soundSource.playSound(sound : SoundExpression [, count : Number])
|
|
|
|
|
|
|
|
|
|
Load a sound and play it.
|
|
|
|
|
*/
|
2011-01-20 19:52:01 +00:00
|
|
|
|
defineMethod(SoundSource.prototype, "playSound", function playSound(sound, count)
|
2011-01-06 19:09:01 +00:00
|
|
|
|
{
|
|
|
|
|
this.sound = sound;
|
|
|
|
|
this.play(count);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-01-20 19:52:01 +00:00
|
|
|
|
/**** Default implementations of script methods ****/
|
2012-11-02 11:11:11 +00:00
|
|
|
|
/* (Note: oolite-default-ship-script.js methods aren’t inherited.)
|
2011-01-27 19:50:13 +00:00
|
|
|
|
*/
|
2011-01-20 19:52:01 +00:00
|
|
|
|
|
|
|
|
|
const escortPositions =
|
|
|
|
|
[
|
|
|
|
|
// V-shape escort pattern
|
2011-01-22 20:38:44 +00:00
|
|
|
|
new Vector3D(-2, 0, -1),
|
|
|
|
|
new Vector3D( 2, 0, -1),
|
|
|
|
|
new Vector3D(-3, 0, -3),
|
|
|
|
|
new Vector3D( 3, 0, -3)
|
2011-01-20 19:52:01 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// X-shape escort pattern
|
2011-01-22 20:38:44 +00:00
|
|
|
|
new Vector3D(-2, 0, 2),
|
|
|
|
|
new Vector3D( 2, 0, 2),
|
|
|
|
|
new Vector3D(-3, 0, -3),
|
|
|
|
|
new Vector3D( 3, 0, -3)
|
2011-01-20 19:52:01 +00:00
|
|
|
|
*/
|
|
|
|
|
];
|
|
|
|
|
|
2011-01-21 20:45:35 +00:00
|
|
|
|
const escortPositionCount = escortPositions.length;
|
2011-01-22 20:38:44 +00:00
|
|
|
|
const escortSpacingFactor = 3;
|
2011-01-21 20:45:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Script.prototype.coordinatesForEscortPosition = function default_coordinatesFromEscortPosition(index)
|
2011-01-20 19:52:01 +00:00
|
|
|
|
{
|
2011-01-22 20:38:44 +00:00
|
|
|
|
var highPart = Math.floor(index / escortPositionCount) + 1;
|
2011-01-21 20:45:35 +00:00
|
|
|
|
var lowPart = index % escortPositionCount;
|
2011-01-20 19:52:01 +00:00
|
|
|
|
|
2011-01-22 20:38:44 +00:00
|
|
|
|
var spacing = this.ship.collisionRadius * escortSpacingFactor * highPart;
|
2011-01-20 19:52:01 +00:00
|
|
|
|
|
2011-01-20 20:23:56 +00:00
|
|
|
|
return escortPositions[lowPart].multiply(spacing);
|
2011-01-21 20:45:35 +00:00
|
|
|
|
};
|
2011-01-20 19:52:01 +00:00
|
|
|
|
|
|
|
|
|
|
2011-01-29 21:40:03 +00:00
|
|
|
|
// timeAccelerationFactor is 1 and read-only in end-user builds.
|
2011-01-29 20:45:17 +00:00
|
|
|
|
if (global.timeAccelerationFactor === undefined)
|
|
|
|
|
{
|
|
|
|
|
Object.defineProperty(global, "timeAccelerationFactor",
|
|
|
|
|
{
|
|
|
|
|
value: 1,
|
|
|
|
|
writable: false,
|
|
|
|
|
configurable: false,
|
|
|
|
|
enumerable: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-12 20:52:05 +00:00
|
|
|
|
})(special);
|