Scripts/timecontrol.js |
"use strict";
this.name = "timecontrol";
this.author = "Norby";
this.copyright = "2015 Norby";
this.description= "Set and clear Time Acceleration in Green and Red alert, etc. Need developer release of Oolite.";
this.licence = "CC BY-NC-SA 4.0";
//customizable properties
this.$GreenTAF = 1; //Time Acceleration Factor in green alert (max. 16, 1=turn off)
this.$InjectorsTAF = 2; //maximal Time Acceleration Factor with Injectors
this.$TorusTAF = 4; //maximal Time Acceleration Factor with Torus Jump Drive
this.$TorusTAFWithTorusToSun = 1; //prevent addition with time forwarding in TTS
this.$MinFPS = 20; //maintain at least this FPS
//internal properties, should not touch
this.$ED = null; //the worldscript of EscortDeck
this.$FCB = null; //FrameCallBack pointer
this.$ON = false; //TAF set over 1, needed to set back to 1 after releasing Injectors
this.$PrevFPS = this.$MinFPS;
this.$Timer = null;
this.$Wormholes = []; //store the last wormholes to stop time once only at a new wormhole
//worldscript events
this.startUp = function() {
timeAccelerationFactor = 1;
if( worldScripts.torustosun ) this.$TorusTAF = this.$TorusTAFWithTorusToSun;
this.$ON = false;
this.$ED = worldScripts.escortdeck;
}
/* old solution without FCB
this.alertConditionChanged = function(newCondition, oldCondition) {
if( newCondition == 3 || player.alertHostiles ) { //red alert
timeAccelerationFactor = 1;
} else if( newCondition == 1 ) { //green alert
timeAccelerationFactor = this.$GreenTAF;
}
}
*/
this.shipDockedWithStation = function() {
timeAccelerationFactor = 1; //as in TAF Reset OXP
this.$ON = false;
if( isValidFrameCallback( this.$FCB ) )
removeFrameCallback( this.$FCB );
if( this.Timer ) {
this.$Timer.stop();
delete this.$Timer;
}
}
this.shipLaunchedFromStation = function() {
this.$PrevFPS = this.$MinFPS;
if( !isValidFrameCallback( this.$FCB ) )
this.$FCB = addFrameCallback( this.$TimeControl_FCB );
if( !this.$Timer ) this.$Timer = new Timer(this, this.$Timed.bind(this), 4, 4);
}
//TimeControl methods
this.$TimeControl_FCB = function( delta ) { //FrameCallBack to adjust TAF based on FPS
var ws = worldScripts.timecontrol;
var minfps = ws.$MinFPS; //maintain at least this FPS
var ps = player.ship;
if( !ps || player.alertCondition > 2 ) { //Red Alert
timeAccelerationFactor = 1;
ws.$ON = false;
// log(ws.name, "Off by red alert");
} else {
//max. TAF adjusted to keep FPS over minfps
var taf = timeAccelerationFactor;
var fps = 100;
if( delta > 0 ) fps = taf / delta;
fps = ( ws.$PrevFPS + fps ) / 2; //average needed to skip accidentally zero delta
ws.$PrevFPS = fps;
if( fps < minfps ) {
if( taf > 1 && ws.$ON ) {
timeAccelerationFactor--;
// log(ws.name, "Reduced by minfps, fps:"+fps);
}
} else {
if ( ps.speed > ps.maxSpeed * 7 + 10 ) { //Torus
if( ws.$TimeControl_Proximity(ws) ) { //turn off near asteroids
timeAccelerationFactor = 1;
ws.$ON = false;
// log(ws.name, "Off by proximity");
} else if( ws.$TorusTAF > 1 ) {
if( taf < ws.$TorusTAF ) timeAccelerationFactor++;
else if( taf > ws.$TorusTAF && ws.$ON )
timeAccelerationFactor = ws.$TorusTAF;
ws.$ON = true;
}
} else if ( ps.speed > ps.maxSpeed + 10 ) { //Injector
if( taf < ws.$InjectorsTAF ) timeAccelerationFactor++;
else if( taf > ws.$InjectorsTAF && ws.$ON )
timeAccelerationFactor = ws.$InjectorsTAF;
ws.$ON = true;
} else if ( player.alertCondition == 1 ) { //Green alert
if( taf < ws.$GreenTAF ) timeAccelerationFactor++;
else if( taf > ws.$GreenTAF && ws.$ON )
timeAccelerationFactor = ws.$GreenTAF;
ws.$ON = true;
} else if( ws.$ON ) { //turn off TAF only if turned on by this script
timeAccelerationFactor = 1;
ws.$ON = false;
// log(ws.name, "Off by condition");
}
}
}
// log(ws.name, "ON:"+ws.$ON+" "+timeAccelerationFactor+"x TAF "+Math.round(timeAccelerationFactor/delta)+"FPS "+Math.round(ws.$PrevFPS)+"FPSavg "+Math.round(ps.speed)+" speed");
}
this.$TimeControl_Proximity = function(ws) {
var s = player.ship.checkScanner(false);
for( var i = 0; s && s.length > i; i++ ) { //exclude escorts and telescopemarker
if( ws.$ED && ws.$ED.$EscortDeckShip.indexOf(s[i]) == -1
&& s[i].dataKey && s[i].dataKey != "telescopemarker" ) {
return(true);
}
}
return(false);
}
this.$Timed = function() {
function $isWormhole(entity) {
return(entity.isWormhole);
}
if( timeAccelerationFactor > 1 ) { //stop if a new Wormhole is opened near
// var s = ps.checkScanner(false); - does not work, no wormhole in the list
var s = system.filteredEntities(this, $isWormhole, player.ship, player.ship.scannerRange);
for( var i = 0; s && s.length > i; i++ ) {
// log(s[i].name+" "+s[i].isWormhole);//debug
if( s[i] && s[i].isValid && s[i].isWormhole
&& this.$Wormholes.indexOf(s[i]) == -1 ) {
this.$Wormholes.push(s[i]);
timeAccelerationFactor = 1;
this.$ON = false;
log(this.name, "Off by wormhole");
}
}
}
}
|