Scripts/torustosun.js |
"use strict";
this.name = "torustosun";
this.author = "Norby";
this.copyright = "2014 Norbert Nagy";
this.licence = "CC BY-NC-SA 4.0";
this.description = "Reach the Sun faster.";
//http://aegidian.org/bb/viewtopic.php?f=6&t=16704&p=223460#p223405
//-start at 1x when you leave the masslock of planet,
//-increasing exponentially between the planet and sun up to 8x,
//-multipliers over 2x need unpowered weapons,
//-fall down to the base value before the sun,
//-limited to the max value if far from both the sun and planet.
//-unpowered weapons provide 2x time forwarding at torus speeds.
//customizable properties
this.$MaxWithWeapons = 2; //chop the bonus to be able to catch Space Pizzas
this.$MaxTimeFw = 4; //time forwarding at max. multiplier (adjustment, not TAF)
this.$Messages = true; //show messages about the current speed (but no messages with CombatMFD regardless of this)
this.$MessagesWithCombatMFD = false; //send Torus multiplier messages with combatMFD also
this.$TimeFwWeaponsOff = 2; //default time forwarding with offline weapons
this.$MaxMultiplier = 8; //*32*400m/s (Asp) almost fit into the 5 digit NumericHUD
//internal properties, should not touch
this.$TimeFw = 1; //actual time forwarding, checked in CombatMFD
this.$TorusToSunBonus = 1; //current speed multiplier, checked in CombatMFD
this.$DBonus = ""; //the lastly displayed speed multiplier
this.$DMore = false; //the lastly displayed more need offline weapons message
this.$FCB = null; //framecallback
this.$FwSec = 0; //part of a second during forwarding
this.$NearestPlanet = null; //store the nearest planet between rechecks
this.$PrevEnergy = 0; //previous energy value of player
this.$Timer = null; //Timer for Torus speedup
this.$WED = null; //the worldscript of EscortDeck
this.$WFP = null; //store worldScripts.farplanets
//world script events
this.startUp = function() {
this.$WED = worldScripts.escortdeck;
this.$WFP = worldScripts.farplanets;
// var n = worldScripts.numerichudv3;
// if( n && n.version * 1 >= 3.24 ) this.$Messages = false;
this.$Timer = new Timer(this, this._Timed.bind(this), 1, 0.25);
this._StopTimer(); //pause timer
}
this.alertConditionChanged = function(newCondition, oldCondition) {
// log("alertConditionChanged", newCondition + "::" + oldCondition)
if (newCondition == 1) {
this._StartTimer();
} else {
this._StopTimer();
}
}
this.shipWillDockWithStation = function() {
this._StopTimer();
}
this.shipWillEnterWitchspace = function() {
this._StopTimer();
}
this.shipWillExitWitchspace = function() {
this._StartTimer(); //must start before Telescope FCBs!
}
this.shipWillLaunchFromStation = function() {
this._StartTimer(); //must start before Telescope FCBs!
}
//TorusToSun functions
this._FCB = function( delta ) { //masslockcheck in this framecallback
var b = this.$TorusToSunBonus;
var ps = player.ship;
if( !ps ) return; //player is died
// log("TorusToSun", "speed: "+Math.round(ps.speed)+" velocity: "+Math.round(ps.velocity.magnitude())); //debug
if( player.alertCondition > 1 || ps.speed < ps.maxSpeed * 31.9 //not in full torus
|| this.$WFP && //FarPlanets OXP active
( this.$WFP.$FarPlanetsSlowDown || this.$WFP.$FarPlanetsBonus > 1 )
|| this._Proximity(this) ) //turn off near asteroids
this._TorusSlowDown(); //do not apply TorusToSun
if( !this.$SlowDown && b > 1 ) { //currently travel at bonus speeds
var f = ps.vectorForward;
var s = ps.maxSpeed * 32;
var t = this.$TimeFw - 1; //torus speed with time forwarding
ps.position = ps.position.add( f.multiply( delta * s * ( t + b - 1 ) ) ); //apply speed bonus
} else {
if( isValidFrameCallback( this.$FCB ) )
removeFrameCallback( this.$FCB );
}
}
this._NearestMass = function(skip) {
var d = 100000000000000000000.0; //10^20m for sure
var psp = player.ship.position;
var nm = null;
var p = system.planets;
var len = p.length;
for( var i = 0; i < len; i++ ) { //find the smallest distance
var pl = p[i];
if( pl != skip ) { //the second nearest if requested
var s = psp.distanceTo( pl.position );
if( d > s ) {
d = s;
nm = pl;
}
}
}
return( nm );
}
this._Proximity = function(ws) { //there is a similar function in TimeControl oxp, if changed then must change both!
var s = player.ship.checkScanner(false);
for( var i = 0; s && s.length > i; i++ ) { //exclude escorts and telescopemarker
if( ws.$WED && ws.$WED.$EscortDeckShip.indexOf(s[i]) == -1
&& s[i].dataKey && s[i].dataKey != "telescopemarker" ) {
return(true);
}
}
return(false);
}
this._StartTimer = function() {
this.$PrevEnergy = player.ship.maxEnergy;
this.$FwSec = 0; //part of a second during forwarding
if( this.$Timer ) {
this.$Timer.start();
}
}
this._StopTimer = function() {
if( this.$Timer ) {
this.$Timer.stop();
}
if( isValidFrameCallback( this.$FCB ) )
removeFrameCallback( this.$FCB );
this._TorusSlowDown(); //set bonus to 1
}
this._Timed = function() {
var ps = player.ship;
if( !ps || !ps.isValid ) return; //player died
if( player.alertCondition == 1 && ps.speed > ps.maxSpeed * 31.9 ) {//Green Alert and Torus maxed
this._TorusSpeedUp();
if( !isValidFrameCallback( this.$FCB ) )
this.$FCB = addFrameCallback( this._FCB.bind(this) );
}
}
this._TimeFw = function( bonus ) { //use time forwarding at maximal bonus if weapons off
if( bonus == this.$MaxMultiplier && !player.ship.weaponsOnline ) return(true);
return(false);
}
this._TorusSlowDown = function() { //slowdown from extreme speed to normal or Torus speeds
if( this.$TorusToSunBonus <= 1 ) return; //need to avoid block Injector speeds
this.$PrevEnergy = player.ship.energy;
this.$TorusToSunBonus = 1; //the main thing for slowdown
this.$DBonus = "";
this.$DMore = false;
this.$SlowDown = true; //flag to FCB
}
this._TorusSpeedUp = function() {
var ps = player.ship;
if( !ps || !ps.isValid || this.$WFP && //FarPlanets OXP active
( this.$WFP.$FarPlanetsSlowDown || this.$WFP.$FarPlanetsBonus > 1 ))
return;
var bonus = 1;
if( ps.equipmentStatus("EQ_TORUSTOSUN") == "EQUIPMENT_OK"
&& system && system.planets && system.planets.length > 0
&& !system.isInterstellarSpace && system.sun && system.sun.isValid
&& !system.sun.hasGoneNova ) {
this.$SlowDown = false;
var co = 1000; //coefficient, larger value cause smaller speeds
var mm = this.$MaxMultiplier;
var sr = system.sun.radius;
var pds = ps.position.distanceTo( system.sun.position ) - sr; //playerDistanceFromSun
//check sun direction and apply gravity pullback, angle=0: aft, angle=PI: front
var angle = ps.vectorForward.angleTo(ps.position.subtract(system.sun.position));
sr = Math.min(sr, 200000); //max. 200km in the following formula
//keep up the high speed much longer when approach the sun
var min = pds / ( 10000 + ( 1 - angle / Math.PI ) * sr *
Math.max( 0, 1 - pds / ( 10 * sr ) ) ); //no gravity pullback over 10 sun radius
bonus = 1 + (mm - 1) * Math.min( 1, min * min / co ); //nonlinear calculation
var nm = this._NearestMass();
var nr = Math.max(nm.radius, 50000); //min. 50k to reduce speeds near small moons
var pdp = ps.position.distanceTo( nm.position ) - 2 * nr; //playerDistanceFromPlanet
min = pdp / nr;
var b1 = 1 + (mm - 1) * Math.min( 1, min * min / co ); //nonlinear calculation
bonus = Math.min(b1, bonus); //use the smaller bonus
var nm2 = this._NearestMass(nm); //the second nearest mass
if( nm2 ) {
var nr2 = Math.max(nm2.radius, 50000); //min. 50k to reduce speeds near small moons
var pdp2 = ps.position.distanceTo( nm2.position ) - 2 * nr2; //playerDistanceFromPlanet2
min = pdp2 / nr2;
var b2 = 1 + (mm - 1) * Math.min( 1, min * min / co ); //nonlinear calculation
bonus = Math.min(b2, bonus); //use the smallest bonus
}
// log("TorusToSun", " bonus:"+bonus+" pdp:"+pdp+" pds:"+pds+" nm:"+nm); //debug
}
if( ps.weaponsOnline ) bonus = Math.min(bonus, this.$MaxWithWeapons);
if( bonus > 1 ) { //show speed bonus, apply will happen in FCB
var b = Math.round( bonus );
if( this._TimeFw( bonus ) ) this.$TimeFw = this.$MaxTimeFw;
else if( !ps.weaponsOnline ) this.$TimeFw = this.$TimeFwWeaponsOff; //2x
else this.$TimeFw = 1; //no time forward with online weapons
if( this.$TimeFw > 1 ) {
var delta = 0.25; //0.25sec timer
//calculate the bonus time plus add the previous remainder
var sec = delta * ( this.$TimeFw - 1 ) + this.$FwSec;
// log("TorusToSun", " bonus:"+bonus+" mm:"+mm+" sec:"+sec); //debug
if( sec >= 1 ) {
var maxsec = 2592000; //not allowed to add more sec in one step
if( sec < maxsec ) clock.addSeconds( Math.floor( sec ) ); //add the integer part
else {
var sec2 = Math.floor( sec / maxsec );
for(var i=0; i<sec2; i++) clock.addSeconds( maxsec );
clock.addSeconds( sec - maxsec * sec2 );
}
// log("TorusToSun", this.$TimeFw+"x added "+sec+"s = "+(sec/86400)+" day"); //debug
this.$FwSec = sec - Math.floor( sec ); //save the remainder
} else this.$FwSec = sec;
if( this.$PrevEnergy < ps.energy && ps.energy < ps.maxEnergy - 1 ) {
//recharge speed up scaled with forwarding
ps.energy += ( ps.energy - this.$PrevEnergy ) * sec / delta;
}
}
if( this.$Messages && !this.$DMore && ps.weaponsOnline
&& bonus == this.$MaxWithWeapons ) {
this.$DMore = " - more need offline weapons";
player.consoleMessage( "Torus " + b + "x" + this.$DMore, 5 );
} else {
if( this.$Messages && this.$DBonus != b && ( this.$MessagesWithCombatMFD
|| ps.equipmentStatus("EQ_COMBATMFD") != "EQUIPMENT_OK" ) ) {
player.consoleMessage( "Torus " + b + "x", 5 );
}
}
if( bonus < this.$MaxWithWeapons) this.$DMore = false; //prevent repeated message
this.$PrevEnergy = ps.energy;
this.$TorusToSunBonus = bonus;
this.$DBonus = b; //save last message to avoid repeat
} else this._TorusSlowDown(); //slowdown
}
|