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
|
2011-01-02 20:27:12 +00:00
|
|
|
|
Copyright © 2004-2011 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
|
|
|
|
// NOTE: for jslint to work, you must comment out the use of __proto__.
|
|
|
|
|
/*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";
|
2011-01-02 20:27:12 +00:00
|
|
|
|
this.copyright = "© 2009-2011 the Oolite team.";
|
2010-06-13 15:40:59 +00:00
|
|
|
|
this.version = "1.75";
|
2008-02-24 21:07:20 +00:00
|
|
|
|
|
|
|
|
|
|
2011-01-06 16:28:13 +00:00
|
|
|
|
/**** Built-in in ECMAScript 5, to be removed when Linux builds transition ****/
|
|
|
|
|
|
|
|
|
|
// Object.defineProperty: only value key is supported. Getter and setter are possible, but not required.
|
|
|
|
|
if (typeof Object.defineProperty !== "function")
|
|
|
|
|
{
|
|
|
|
|
Object.defineProperty = function (object, name, definition)
|
|
|
|
|
{
|
|
|
|
|
object[name] = definition.value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Object.getPrototypeOf(): ECMAScript 5th Edition eqivalent to __proto__ extension.
|
|
|
|
|
if (typeof Object.getPrototypeOf !== "function")
|
|
|
|
|
{
|
|
|
|
|
Object.getPrototypeOf = function (object)
|
|
|
|
|
{
|
|
|
|
|
return object.__proto__;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* string.trim(): remove leading and trailing whitespace.
|
|
|
|
|
Implementation by Steve Leviathan, see:
|
|
|
|
|
http://blog.stevenlevithan.com/archives/faster-trim-javascript
|
|
|
|
|
Note: as of ECMAScript 5th Edition, this will be a core language method.
|
|
|
|
|
*/
|
|
|
|
|
if (typeof String.prototype.trim !== "function")
|
|
|
|
|
{
|
|
|
|
|
String.prototype.trim = function String_trim()
|
|
|
|
|
{
|
|
|
|
|
var str = this.replace(/^\s\s*/, ''),
|
|
|
|
|
ws = /\s/,
|
|
|
|
|
i = str.length;
|
|
|
|
|
while (ws.test(str.charAt(--i))) {}
|
|
|
|
|
return str.slice(0, i + 1);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Array.isArray(object): true if object is an array.
|
|
|
|
|
if (typeof Array.isArray !== "function")
|
|
|
|
|
{
|
|
|
|
|
Array.isArray = function Array_isArray(object)
|
|
|
|
|
{
|
|
|
|
|
return object && object.constructor === [].constructor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-01-06 19:09:01 +00:00
|
|
|
|
// Utility to define non-enumerable, permanent methods, to match the behaviour of native methods.
|
|
|
|
|
this.defineMethod = function(object, name, implementation)
|
|
|
|
|
{
|
|
|
|
|
Object.defineProperty(object, name, { value: implementation, writable: false, enumerable: false });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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-06 19:09:01 +00:00
|
|
|
|
this.defineMethod(Ship.prototype, "spawnOne", function (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-11 22:14:03 +00:00
|
|
|
|
this.defineMethod(Mission.prototype, "addMessageTextKey", function (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
|
|
|
|
|
|
|
|
|
|
2009-09-05 18:19:23 +00:00
|
|
|
|
/* SystemInfo.systemsInRange(): return SystemInfos for all systems within a
|
|
|
|
|
certain distance.
|
|
|
|
|
*/
|
2011-01-06 19:09:01 +00:00
|
|
|
|
this.defineMethod(SystemInfo, "systemsInRange", function (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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Default to using the current system.
|
|
|
|
|
var thisSystem = system.info;
|
|
|
|
|
|
|
|
|
|
// If called on an instance instead of the SystemInfo constructor, use that system instead.
|
|
|
|
|
if (this !== SystemInfo)
|
|
|
|
|
{
|
|
|
|
|
if (this.systemID !== undefined && this.distanceToSystem !== undefined)
|
2010-06-13 16:00:30 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
thisSystem = this;
|
2010-06-13 16:00:30 +00:00
|
|
|
|
}
|
2011-01-06 19:09:01 +00:00
|
|
|
|
else
|
2010-06-13 16:00:30 +00:00
|
|
|
|
{
|
2011-01-06 19:09:01 +00:00
|
|
|
|
special.jsWarning("systemsInRange() called in the wrong context. Returning empty array.");
|
|
|
|
|
return [];
|
2010-06-13 16:00:30 +00:00
|
|
|
|
}
|
2011-01-06 19:09:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SystemInfo.filteredSystems(this, function (other)
|
|
|
|
|
{
|
|
|
|
|
return (other.systemID !== thisSystem.systemID) && (thisSystem.distanceToSystem(other) <= range);
|
|
|
|
|
});
|
2011-01-06 12:05:16 +00:00
|
|
|
|
});
|
2009-09-05 18:19:23 +00:00
|
|
|
|
|
|
|
|
|
|
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-11 22:14:03 +00:00
|
|
|
|
this.defineMethod(System.prototype, "scrambledPseudoRandomNumber", function (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-06 19:09:01 +00:00
|
|
|
|
/* soundSource.playSound(sound : SoundExpression [, count : Number])
|
|
|
|
|
|
|
|
|
|
Load a sound and play it.
|
|
|
|
|
*/
|
|
|
|
|
this.defineMethod(SoundSource.prototype, "playSound", function (sound, count)
|
|
|
|
|
{
|
|
|
|
|
this.sound = sound;
|
|
|
|
|
this.play(count);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete this.defineMethod;
|