Config/script.js |
"use strict";
this.name = "combat_MFD";
this.author = "Norby, Zireael";
this.copyright = "2014 Norby, Zireael";
this.description = "Makes MFDs more useful by displaying some info";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.17";
this.$DW = 28; //default width of centered textfields in setCustomHUDDial
this.$ExactNumbers = false; //energy and shield values for debug
this.$combat_MFD = null; //store the final displayed string with player and target data
this.$Data = {}; //storage of calculated values for external usage
this.$DataArray = [ //data_source key names for drawCustomText and drawCustomBar HUD dials
"combatAftSh", //aft shield numeric value (including capacitors)
"combatAftShBar", //aft shield bar including capacitors
"combatAftShP", //aft shield percent value (over 100% if upgraded)
"combatAlt", //altitude over the nearest planet, moon or sun in km
"combatAltR", //altitude over a planet, moon or sun in radius
"combatCargoBar", //how filled the cargo bay of player ship
"combatCredits", //credits of player
"combatCTemp", //cabin temp
"combatDmgEq", //name of the lastly damaged equipment
"combatDEqNum", //number of the damaged equipments
"combatEnergy", //energy of player ship in numeric form
"combatEnergyP", //energy of player ship in percent
"combatFwSh", //forward shield numeric value (including capacitors)
"combatFwShBar", //forward shield bar including capacitors
"combatFwShP", //forward shield percent value (over 100% if upgraded)
"combatFuel", //remaining fuel in the main tank in ly (min. 0.0, max. 7.0)
"combatFuelReq", //required fuel of a declared hyperjump
"combatFuelRes", //reserve fuel in extra tanks (integer)
"combatLegal", //legal status of player (word)
"combatLegalNum", //legal status of player (number)
"combatNewTelT", //name of the newest target detected by Telescope
"combatOneShot", //letters of One-shot indicator (BCEGHPRU)
"combatSCTDist", //distance of space compass target
"combatSEE", //letters of SEE indicator about the player ship (CMBSAHE)
"combatSEEBar", //total durability bar of player ship based on the SEE indicator
"combatSEEMax", //maximum number of ship durability: max of shield+armour+energy
"combatSEENum", //number of ship durability: shield+armour+energy
"combatSLBar", //service level bar of player ship
"combatSpeed", //actual speed of player ship in m/s
"combatTDist", //distance of the current target
"combatTDmg", //damaged/weak/derelict status of the current target
"combatTEnergy", //energy of the current target, use for debug only
"combatTLaser", //laser weapon of the current target
"combatTLegal", //legal status of the current target, if derelict then Towbar status
"combatTLRange", //range of the target's laser weapon
"combatTMissile", //missile type fired by the target (Hard, etc.)
"combatTMissNum", //number of missiles fired by the target so far
"combatTName", //full name of the current target
"combatTRadius", //shield radius of the current target
"combatTSpeed" //speed of the current target
];
this.$DataShow = {}; //allow or deny display of the mentioned values in CustomHUDDial
this.$DmgEqs = []; //store damaged eq keys
this.$InfoTimer = null; //store pointer to timer
this.$InfoTimer2 = null; //store pointer to timer2
this.$TelescopeLine = ""; //the 5. line in this MFD is filled by Telescope_1.9.oxz
this.$WasOk = false; //store the previous state of Equipment
this.$lastTarget = null;
this._altimeterDecimals = 3;
this.startUp = function () {
var h = worldScripts.hudselector;
if (h && h.$HUDSelectorAddMFD) h.$HUDSelectorAddMFD(this.name);
for (var i = 0; i < this.$DataArray.length; i++) {
this.$Data[this.$DataArray[i]] = 0; //fill up Data object with key names
this.$DataShow[this.$DataArray[i]] = true; //allow display all data by default
}
if (player.ship && player.ship.isValid)
this.$PlayerPrevPos = player.ship.position;
else this.$PlayerPrevPos = [0, 0, 0];
this.$Target = null;
this.$TargetPrevPos = [0, 0, 0];
this.$Aws = worldScripts.andromeda;
this.$Cws = worldScripts["Automatic ECM System"];
this.$Dws = worldScripts.duplex_fuel_tank;
this.$Ews = worldScripts["extra_tanks_script.js"];
this.$Hws = worldScripts.hardships;
this.$Iws = worldScripts["IronHide Armour Script"];
this.$Sca = worldScripts.ShipConfiguration_Armour;
this.$Ows = worldScripts.towbar;
this.$Rws = worldScripts.torustosun;
this.$Sws = worldScripts.shieldequalizercapacitors;
this.$Scs = worldScripts["Shield Cycler"];
this.$Tws = worldScripts.telescope;
this.$Uws = worldScripts["Turret Toggler"];
this.$InfoTimer = null; //store pointer to timer
this.$InfoTimer2 = null; //store pointer to timer2
this.$DmgEqs = []; //store damaged eq keys
var eq = player.ship.equipment;
var i = -1;
while (eq[++i]) { //skip noname eqs awarded by NumericHUD
if (eq[i].name.length > 0
&& player.ship.equipmentStatus(eq[i].equipmentKey) == "EQUIPMENT_DAMAGED")
this.$DmgEqs.push(eq[i].equipmentKey);
}
}
this.equipmentDamaged = function (equipment) {
this.$DmgEqs.push(equipment);
// log("combat_MFD", "DmgEqs: "+this.$DmgEqs); //debug
}
this.shipAttackedWithMissile = function (missile, whom) {
if (whom && whom.script) {
if (whom.script.$combat_MFD_missiles && whom.script.$combat_MFD_missiles > 0)
whom.script.$combat_MFD_missiles++;
else whom.script.$combat_MFD_missiles = 1;
if (missile.dataKey == "missile")
whom.script.$combat_MFD_normalmissile = true;
else if (missile.dataKey == "ecm-proof-missile")
whom.script.$combat_MFD_hardmissile = true;
}
}
this.shipBeingAttacked = this.shipBeingAttackedUnsuccessfully = function (whom) {
if (whom && whom.script) whom.script.$combat_MFD_attacked = true; //flag for display Laser type
}
this.shipTargetAcquired = function (target) {
this.$showCombatInfo(); //update MFD
}
this.shipTargetLost = function (losttarget) {
this.$showCombatInfo(); //update MFD
}
this.shipWillDockWithStation = function () {
this.$TelescopeLine = "";
if (this.$InfoTimer) {
this.$InfoTimer.stop();
delete this.$InfoTimer;
}
var p = player.ship;
if (p.setCustomHUDDial) //need Oolite v1.81
for (var key in this.$Data) p.setCustomHUDDial(key, ""); //clear custom dials
}
this.shipWillEnterWitchspace = function () {
this.$TelescopeLine = "";
}
this.shipWillLaunchFromStation = function () {
//the timer interval is bound to the multipliers in speed calculations so must change together
if (!this.$InfoTimer) {
this.$InfoTimer = new Timer(this, this.$showCombatInfo.bind(this), 0, 0.25);
if (this.$Sws) { //turn of irritating messages and sounds which is unneccesary with this MFD
this.$Sws.togglemessages = "OFF";
this.$Sws.togglesoundfx2 = "OFF";
}
}
//log("CombatMFD",player.ship.equipmentStatus("EQ_COMBATMFD")+" "+this.$InfoTimer);//debug
this.$InfoTimer2Done = false;
if (this.$ExactNumbers) {//debug
var s = system.addShips("pirate", 1,
system.mainStation.position.add(player.ship.heading.multiply(3000)), 100);//debug target
if (s && s[0]) {
//s[0].forwardWeapon = null;//setAI("nullAI.plist");
s[0].bounty = 1;
s[0].target = player.ship;
//s[0].displayName = s[0].name + " Target";
}
}
}
this.$showCombatInfo = function $showCombatInfo () {
var that = $showCombatInfo;
var _p = (that._p = that._p || player.ship);
var _decimals = (that._decimals = that._decimals || this._altimeterDecimals);
//var p = player.ship;
// log("combat_MFD", "EQ_COMBATMFD: "+p.equipmentStatus("EQ_COMBATMFD")); //debug
if (!_p || !_p.isValid) return;
if (this.$WasOk && _p.equipmentStatus("EQ_COMBATMFD") == "EQUIPMENT_DAMAGED") {
this.$WasOk = false;
_p.removeEquipment("EQ_DTADER"); //remove text legends in NumericHUD
_p.removeEquipment("EQ_DTADAM");
_p.removeEquipment("EQ_DTAWEA");
_p.setMultiFunctionText(this.name, "Combat MFD is damaged", false);
}
var pp = _p.position;
var target = "\n\n\n\n"; //gather data of player's current target, skip the lines if no target
var ceq = false;
//always clear combatT dials for sure (no eq, no target or not applicable due to other reason)
this.$setData("combatTDist", ""); //distance of the current target
this.$setData("combatTDmg", ""); //damaged/weak/derelict status of the current target
this.$setData("combatTEnergy", ""); //energy of the current target, use for debug only
this.$setData("combatTLaser", ""); //laser weapon of the current target
this.$setData("combatTLegal", ""); //legal status of the current target, if derelict then Towbar status
this.$setData("combatTLRange", ""); //range of the target's laser weapon
this.$setData("combatTMissile", ""); //missile type fired by the target (Hard, etc.)
this.$setData("combatTMissNum", ""); //number of missiles fired by the target so far
this.$setData("combatTName", ""); //full name of the current target
this.$setData("combatTRadius", ""); //shield radius of the current target
this.$setData("combatTSpeed", ""); //speed of the current target
if (_p.equipmentStatus("EQ_COMBATMFD") == "EQUIPMENT_OK") {
var ceq = true;
this.$WasOk = true;
var t = _p.target;
if (t != this.$lastTarget) {
_p.removeEquipment("EQ_DTADER"); //remove text legends in NumericHUD
_p.removeEquipment("EQ_DTADAM");
_p.removeEquipment("EQ_DTAWEA");
this.$lastTarget = t;
}
if (t && t.isValid) {
var tdn = t.displayName;//must read name before handle telescopemarker
var st = "";
if (t.isWormhole) {
tdn = "Wormhole";
if (_p.equipmentStatus("EQ_WORMHOLE_SCANNER") == "EQUIPMENT_OK") {
if (this.$InfoTimer2Done && this.$LastWormhole == t) {
//log("CombatMFD",t.expiryTime+" "+clock.seconds+" "+t.arrivalTime);//debug
if (t.destination) tdn += " to " + System.systemNameForID(t.destination);
if (t.expiryTime) tdn = this.$AlignedText(tdn, "expire in " +
Math.round(t.expiryTime - clock.seconds) + " s");
if (t.arrivalTime) {
st = "Travel Time: " + (Math.round(
(t.arrivalTime - clock.seconds) / 360) / 10) + " h";
this.$setData("combatTLegal", st);
}
} else { //5s delay before show Wormhole info
tdn += " scanning...";
if (this.$LastWormhole != t) {
this.$LastWormhole = t;
this.$InfoTimer2Done = false;
if (this.$InfoTimer2) {
this.$InfoTimer2.stop();
delete this.$InfoTimer2;
}
this.$InfoTimer2 = new Timer(this, this.$showWormholeInfo.bind(this), 6);
}
}
}
}
//telescope far target over scanner range
var t2 = null;
if (this.$Tws && t.dataKey == "telescopemarker") {//change the pointer to the real target
t2 = this.$Tws.$TelescopeList[this.$Tws.$TelescopeListi - 1];
//this.$Tws.$TelescopeTarget is not good: not refreshed when
//the target is changed automatically in weapons offline mode
if (t2 && t2.isValid) t = t2;
var k = tdn.indexOf("km "); //chop the x km from the begin of marker name
if (k > -1 && k < 10) tdn = tdn.substr(k + 3);
}
this.$setData("combatTName", tdn);
//target speed
var tsp = 0;
var ts = "0";
if (t.maxSpeed > 0) {
if (t.speed > t.maxSpeed * t.injectorSpeedFactor || (t.speed == 0 && t.velocity.magnitude() != 0)) { // only do the calc if the speed value is greater than the maxspeed setting
if (this.$Target == t) { //need 2 pos. for speed, use velocity for Q-Charger
tsp = Math.round(t.velocity.magnitude() / 10) * 10; //stable but can not show FTL drive
if (tsp > 31 * t.maxSpeed) { //support for FarPlanets
var psp = Math.round(0.1 * t.position.distanceTo(this.$TargetPrevPos)) * 10;
if (psp > 1.1 * tsp) tsp = psp;//instable but need to follow position changes
}
} else {
this.$Target = t; //first time save position
tsp = Math.round(t.velocity.magnitude() / 10) * 10;
}
if (tsp > 10000000) tsp = Math.round(tsp / 1000000) + " M";
else if (tsp > 1000000) tsp = Math.round(tsp / 1000) + " k";
else tsp = Math.round(tsp) + " ";
ts = tsp;
tsp += "m/s";
} else {
// otherwise, we can just rely on the standard speed value
ts = t.speed.toFixed(0) + " ";
tsp = ts + "m/s";
}
//tsp = "Speed: " + tsp;
} else tsp = ""; //nothing for stationary objects, zero for others
this.$setData("combatTSpeed", ts, this.$DW);
this.$TargetPrevPos = t.position;
//target distance
var ra = Math.round(t.collisionRadius);
var di = Math.max(0, Math.round(t.position.distanceTo(pp) - ra - _p.collisionRadius));
if (di >= 1000000000) di = Math.floor(di / 1000000000) + "Mkm";
else if (di >= 1000) di = Math.floor(di / 1000) + "km";
else di += "m";
this.$setData("combatTDist", di, this.$DW);
if (ra > 100000) ra = Math.round(ra / 1000) + "km";
else ra += "m";
//target radius
var sr = "";
if (!t.isShip || t.isPlanet || t.isSun || t.isRock) {
sr = "Radius: " + ra;
this.$setData("combatTRadius", sr);
// this.$setData("combatTDmg", "");
} else { //facing shield
if (!t2) { //within scanner range only
sr = "Shield Radius: ";
if (this.$AftShieldFacing(t)) sr = sr + ra + " Aft";
else sr = sr + ra + " Front";
this.$setData("combatTRadius", sr);
}
var d = false;
if (t.isDerelict) {
d = "Derelict";
// log(this.name, "Awarding DTADER, target is derelict");
_p.awardEquipment("EQ_DTADER"); //show text legend in NumericHUD
} else {
if (!t2 && t.energy && t.maxEnergy) {
if (t.energy < 0.2 * t.maxEnergy) {
d = "Weak!";
_p.awardEquipment("EQ_DTAWEA");
} else if (t.energy < 0.4 * t.maxEnergy) {
d = "Damaged!";
_p.awardEquipment("EQ_DTADAM");
}
}
}
if (d) {
sr = this.$AlignedText(sr, d);
this.$setData("combatTDmg", d);
} //else this.$setData("combatTDmg", "");
}
//target laser
var laser = "";
if (t.script && t.script.$combat_MFD_attacked && t.currentWeapon) {
laser = "Laser: " + t.currentWeapon.name;
this.$setData("combatTLaser", laser);
var rng = "Range: " + Math.round(t.weaponRange / 100) / 10 + "km";
this.$setData("combatTLRange", rng);
laser = this.$AlignedText(laser, rng);
} else if (t.forwardWeapon) {
laser = "Laser: Unknown";
this.$setData("combatTLaser", laser);
// this.$setData("combatTLRange", "");
}
//target status
if (!t2 && _p.equipmentStatus("EQ_SCANNER_SHOW_MISSILE_TARGET") == "EQUIPMENT_OK"
&& (!t.isWormhole && t.isShip && t.isPiloted || t.isDerelict)) {
st = "Status:";
if (t.isDerelict) {
if (this.$Ows && t.script) { //Towbar status
if (t.script.$TowbarUsableShip) st += " Usable!";
else if (t.script.$TowbarMinedShip) st += " Mined";
if (t.script.$TowbarEmptyShip) st += " Empty";
else st += " Trap or Treasure";
}
} else if (t.bounty > 50) st += " Fugitive"; //legal status
else if (t.bounty > 0) st += " Offender";
else st += " Clean";
this.$setData("combatTLegal", st);
if (this.$ExactNumbers) st += " " + Math.round(t.energy);//for debug
this.$setData("combatTEnergy", Math.round(t.energy), this.$DW);
// this.$setData("combatTMissNum", 2); this.$setData("combatTMissile", "Normal");//debug
//Missiles fired
if (t.script) {
var m = t.script.$combat_MFD_missiles;
if (m > 0) {
this.$setData("combatTMissNum", m);
var s = "";
if (m > 1) s = "s";
if (t.script.$combat_MFD_hardmissile) {
m += " Hard";
this.$setData("combatTMissile", "Hard");
} else if (t.script.$combat_MFD_normalmissile) {
this.$setData("combatTMissile", "Normal");
} else {
m += " Unknown type";
this.$setData("combatTMissile", "Unknown");
}
st = this.$AlignedText(st, " Missile" + s + " fired: " + m);
}
}
}
//concatenate target info
target = tdn + "\n" + this.$AlignedText("Distance: " + di + ", Mass: " + (t.mass / 1000).toFixed(1) + "t", tsp) +
"\n" + sr + "\n" + laser + "\n" + st;
}
else {
_p.removeEquipment("EQ_DTADER"); //remove text legends in NumericHUD
_p.removeEquipment("EQ_DTADAM");
_p.removeEquipment("EQ_DTAWEA");
this.$Target = null;
}
}
//player energy
this.$setData("combatEnergy", Math.round(_p.energy), this.$DW);
var ep = "Energy: " + 10 * Math.round(10 * _p.energy / _p.maxEnergy) + "%";
this.$setData("combatEnergyP", ep, this.$DW);
var eb = Math.floor(_p.maxEnergy / 64);//how many energy banks shown in hud
var e = Math.ceil(_p.energy / (_p.maxEnergy / eb));
var en = "";
var seemax = _p.maxEnergy;
var ihv = 0;
if (this.$Iws) { //IronHide armour
var ihs = missionVariables.ironHide_strength;
seemax += ihs;
var ihp = missionVariables.ironHide_percentage;
if (ihs > 0 && ihp > 0) ihv = ihs * (ihp / 100);
// log("combat_MFD", "H: "+ihs+" "+ihp+" "+ihv); //debug
}
var asmax = _p.maxAftShield;
var fsmax = _p.maxForwardShield;
seemax += Math.max(asmax, fsmax);
if (this.$Sws && //Shield capacitor
(_p.equipmentStatus("EQ_FORWARD_SHIELD_CAPACITOR") != "EQUIPMENT_UNAVAILABLE"
|| _p.equipmentStatus("EQ_AFT_SHIELD_CAPACITOR") != "EQUIPMENT_UNAVAILABLE")) {
var max = 64;
if (this.$Sws.secforwardshieldcapacitormax) {
max = Math.max(max, this.$Sws.secforwardshieldcapacitormax);
fsmax += this.$Sws.secforwardshieldcapacitormax;
} else if (_p.equipmentStatus("EQ_FORWARD_SHIELD_CAPACITOR") == "EQUIPMENT_OK")
fsmax += 64;
if (this.$Sws.secaftshieldcapacitormax) {
max = Math.max(max, this.$Sws.secaftshieldcapacitormax);
asmax += this.$Sws.secaftshieldcapacitormax;
} else if (_p.equipmentStatus("EQ_AFT_SHIELD_CAPACITOR") == "EQUIPMENT_OK")
asmax += 64;
seemax += max;
en += this.$SEELetters("C", max,
this.$Sws.secforwardshieldcapacitor,
this.$Sws.secaftshieldcapacitor,
"EQ_FORWARD_SHIELD_CAPACITOR",
"EQ_AFT_SHIELD_CAPACITOR",
"EQ_BIGSHCAP", "EQ_BIGSHCAP2", "EQ_BIGSHCAP3");
}
if (this.$Hws) { //armours in HardShips OXP
var hmax = Math.max(this.$Hws.$HardShips_AMax[0][0], //fw
this.$Hws.$HardShips_AMax[0][1]); //aft
seemax += hmax;
}
if (this.$Sca) { // armour in ShipConfig
var scmax = Math.max(_p.script._frontArmourStrength, _p.script._aftArmourStrength);
// lowest max is 100, highest is 400. convert of factors of 128
scmax *= 1.28;
seemax += scmax;
}
if (e < 2 && _p.maxEnergy > 96) { //not exactly below 64, for example in Fer-De-Lance below 75
en = "LAST BANK!";
} else { //"SEE" indicator: letters mean shields, armour and energy for each double banks
if (_p.equipmentStatus("EQ_NAVAL_SHIELD_BOOSTER") != "EQUIPMENT_UNAVAILABLE")
en += this.$SEELetters("M", 128,
Math.max(0, _p.forwardShield - 256),
Math.max(0, _p.aftShield - 256),
"EQ_NAVAL_SHIELD_BOOSTER");
if (_p.equipmentStatus("EQ_SHIELD_BOOSTER") != "EQUIPMENT_UNAVAILABLE")
en += this.$SEELetters("B", 128,
Math.min(128, Math.max(0, _p.forwardShield - 128)),
Math.min(128, Math.max(0, _p.aftShield - 128)),
"EQ_SHIELD_BOOSTER");
en += this.$SEELetters("S", 128,
Math.min(128, _p.forwardShield),
Math.min(128, _p.aftShield),
"EQ_BREAKABLE_SHIELD_FORE_SMALL",
"EQ_BREAKABLE_SHIELD_AFT_SMALL",
"EQ_BREAKABLE_SHIELD_FORE_MEDIUM",
"EQ_BREAKABLE_SHIELD_AFT_MEDIUM",
"EQ_BREAKABLE_SHIELD_FORE_LARGE",
"EQ_BREAKABLE_SHIELD_AFT_LARGE");
if (this.$Hws) { //armours in HardShip OXP
en += this.$SEELetters("A", hmax,
this.$Hws.$HardShips_Armour[0][0], //fw armour value
this.$Hws.$HardShips_Armour[0][1]);//aft
//IronHide handled by HardShips
var ihs = this.$Hws.$HardShips_AMax[0][7];
var ihv = this.$Hws.$HardShips_Armour[0][7];
}
if (ihv > 0) en += this.$SEELetters("H", ihs, ihv, ihv);
if (this.$Sca) { // armour in ShipConfig
en += this.$SEELetters("A", scmax, ((_p.script._armourFront / 100) * _p.script._frontArmourStrength) * 1.28, ((_p.script._armourAft / 100) * _p.script._aftArmourStrength) * 1.28);
}
en += this.$SEELetters("E", _p.maxEnergy, _p.energy, _p.energy,
"EQ_BREAKABLE_ENERGY_UNIT_SMALL",
"EQ_BREAKABLE_ENERGY_UNIT_MEDIUM",
"EQ_BREAKABLE_ENERGY_UNIT_LARGE");
}
//"SEE" indicator is done at this point in en variable
this.$setData("combatSEE", en);
//count enery+armour+shield banks
e = _p.energy + Math.min(_p.forwardShield, _p.aftShield);
if (this.$Sws) e += Math.min(this.$Sws.secforwardshieldcapacitor,
this.$Sws.secaftshieldcapacitor);
if (this.$Hws) e += Math.min(this.$Hws.$HardShips_Armour[0][0], //fw
Math.min(this.$Hws.$HardShips_Armour[0][1],//aft
Math.min(this.$Hws.$HardShips_Armour[0][2],//port
Math.min(this.$Hws.$HardShips_Armour[0][3],//sb
Math.min(this.$Hws.$HardShips_Armour[0][4],//top
this.$Hws.$HardShips_Armour[0][5])))));//bottom
e += ihv; //ironhide value, calculated above
en += " (" + Math.round(e / 64) + ")"; //in banks
this.$setData("combatSEEMax", seemax, this.$DW);//maximum of exact SEE value
this.$setData("combatSEENum", Math.round(e), this.$DW);//exact value
this.$setData("combatSEEBar", e / seemax);//0-1
//player shields
var fs = Math.round(_p.forwardShield);
if (this.$Sws) fs += Math.round(this.$Sws.secforwardshieldcapacitor);
this.$setData("combatFwSh", fs, this.$DW);
this.$setData("combatFwShBar", fs / fsmax);
var as = Math.round(_p.aftShield);
if (this.$Sws) as += Math.round(this.$Sws.secaftshieldcapacitor);
this.$setData("combatAftSh", as, this.$DW);
this.$setData("combatAftShBar", as / asmax);
var fp = this.$ForwardPercent(fs);
var ap = this.$AftPercent(as);
var sh = "Shields: " + fp + "%/" + ap + "%";
var ws_sc = this.$Scs;
if (ws_sc && (ws_sc.hasOwnProperty("_sc_get_sc_versions") && (ws_sc._sc_get_sc_versions(null)).version > 0) && !ws_sc.$sc_disabled && ws_sc.$sc_settings.version > 0)
sh += " " + ws_sc.$sc_const.mode_names[ws_sc.$sc_settings.current_configuration];
this.$setData("combatFwShP", fp + "%", this.$DW);
this.$setData("combatAftShP", ap + "%", this.$DW);
if (this.$ExactNumbers) { //for debug
en += ": " + Math.round(_p.energy);
sh += " (" + fs + "/" + as + ")";
}
//Auto ECM and Turret Toggler indicators
var one = "";
if (this.$Cws && missionVariables.autoECM == 1
&& _p.equipmentStatus("EQ_AUTOECM") == "EQUIPMENT_OK") one += " ECM ";
if (this.$Uws && this.$Uws._tt_turret_status == "active"
&& _p.equipmentStatus("EQ_UNI_TURRET") == "EQUIPMENT_OK") one += " Turret ";
if (one.length > 0) one = " " + one + " ";
//"One-shot" indicator for Energy Bomb and one-shot equipments in HardShips OXP
if (_p.equipmentStatus("EQ_ENERGY_BOMB") == "EQUIPMENT_OK") one += "B";
if (this.$Hws) {
if (_p.equipmentStatus("EQ_ADDITIONAL_CORE_HULL") == "EQUIPMENT_OK") one += "C";
if (_p.equipmentStatus("EQ_EEG") == "EQUIPMENT_OK") one += "E";
}
if (_p.equipmentStatus("EQ_GAL_DRIVE") == "EQUIPMENT_OK") one += "G";
if (this.$Hws && _p.equipmentStatus("EQ_HTCAT") == "EQUIPMENT_OK") one += "H";
if (_p.equipmentStatus("EQ_ESCAPE_POD") == "EQUIPMENT_OK") one += "P";
if (this.$Hws && _p.equipmentStatus("EQ_REG") == "EQUIPMENT_OK") one += "R";
if (_p.equipmentStatus("EQ_EEU") == "EQUIPMENT_OK") one += "U";
sh = this.$AlignedText(sh, one);
this.$setData("combatOneShot", one);
//player legal status
var ps = "";
var psw = "Clean";
if (_p.bounty > 50) {
psw = "Fugitive";
ps += psw + " (" + _p.bounty + ")";
if (_p.bounty < 100) ps += " ";
} else if (_p.bounty > 0) {
psw = "Offender";
ps += psw + " (" + _p.bounty + ") ";
if (_p.bounty < 10) ps += " ";
} else ps += "Status: " + psw + " ";
this.$setData("combatLegal", psw);
var b = Math.round(_p.bounty);
if (b == 0) b = "";
this.$setData("combatLegalNum", b, this.$DW);
//player fuel
var extrafuel = "";
var ef = 0;
if (this.$Aws && _p.dataKey == "andromeda-player"
&& this.$Aws.$AndromedaFuelReserve > 0)
ef += this.$Aws.$AndromedaFuelReserve;
if (this.$Dws) { //DuplexFuelTank.oxz
if (_p.equipmentStatus("EQ_DUPLEX_FUEL_TANK_STATE_1") == "EQUIPMENT_OK") ef += 1;
else if (_p.equipmentStatus("EQ_DUPLEX_FUEL_TANK_STATE_2") == "EQUIPMENT_OK") ef += 2;
else if (_p.equipmentStatus("EQ_DUPLEX_FUEL_TANK_STATE_3") == "EQUIPMENT_OK") ef += 3;
}
if (this.$Ews) { //ExtraFuelTanks-v1.4.1.oxz
if (_p.equipmentStatus("EQ_RESERVE_TANK") == "EQUIPMENT_OK") ef += 1;
else if (_p.equipmentStatus("EQ_AUX_TANK") == "EQUIPMENT_OK") ef += 3;
}
if (_p.equipmentStatus("EQ_FUELTANK_MINE") == "EQUIPMENT_OK") { //Fuel_Tank_2.2.oxz
// log(this.name, _p.missiles); //debug
for (var i = 0; i < _p.missiles.length; i++) {
if (_p.missiles[i].equipmentKey == "EQ_FUELTANK_MINE")
ef += 3;
}
}
if (ef > 0) extrafuel = "+" + Math.round(ef); //display total reserve fuel in addition
var f = (_p.fuel).toFixed(1);
this.$setData("combatFuel", f);
this.$setData("combatFuelRes", extrafuel);
ps += " Fuel: " + f + extrafuel + "ly";
var fr = ""; //fuel required for hyperjump
if (_p.targetSystem)
fr = (System.infoForSystem(galaxyNumber, system.info.systemID)
.distanceToSystem(System.infoForSystem(galaxyNumber, _p.targetSystem))
).toFixed(1);
this.$setData("combatFuelReq", fr);
//torus multiplier and player speed
var tm = "";
var sp = 0;
if (_p.speed > _p.maxSpeed * _p.injectorSpeedFactor || _p.script._ficcEngaged) {
sp = Math.round(_p.velocity.magnitude() / 10) * 10; //stable but can not show FTL drive nor Torus multiplier
if (this.$Rws && this.$Rws.$TorusToSunBonus > 1) {
tm = " " + Math.round(this.$Rws.$TorusToSunBonus) + "x";
sp = Math.round(this.$Rws.$TorusToSunBonus * 3.2 * _p.maxSpeed) * 10;
if (this.$Rws.$TimeFw > 1) { //time forwarding active
tm += Math.round(this.$Rws.$TimeFw);
sp *= this.$Rws.$TimeFw;
}
} else {
if (sp > 31 * _p.maxSpeed) { //support for FarPlanets and any other position changer drives
var psp = Math.round(0.1 * pp.distanceTo(this.$PlayerPrevPos)) * 10;
if (psp > 1.1 * sp) sp = psp;//unstable but need to follow position changes
}
}
if (sp > 10000000) sp = Math.round(sp / 1000000) + " M";
else if (sp > 1000000) sp = Math.round(sp / 1000) + " k";
} else {
sp = _p.speed.toFixed(0);
}
this.$setData("combatSpeed", sp, this.$DW);
if (tm.length > 0) sp += "m/s"; else sp += " m/s";
this.$PlayerPrevPos = pp;
//damaged equipment if any
var dm = "";
var dmg = "";
var dmgeqs = [];
// log("combat_MFD", "DmgEqs: "+this.$DmgEqs); //debug
// _p.setEquipmentStatus("EQ_ECM","EQUIPMENT_DAMAGED");//debug
for (var i = 0; i < this.$DmgEqs.length; i++) //remove fixed ones from the damaged list
if (_p.equipmentStatus(this.$DmgEqs[i]) == "EQUIPMENT_DAMAGED")
dmgeqs.push(this.$DmgEqs[i]);
this.$DmgEqs = dmgeqs;
// log("combat_MFD", "DmgEqs: "+this.$DmgEqs); //debug
var b = ""; //hide 0 length value when no damaged eq
if (dmgeqs && dmgeqs.length > 0) { //show the name of the lastly damaged equipment
b = dmgeqs.length;
dmg = EquipmentInfo.infoForKey(dmgeqs[dmgeqs.length - 1]).name;
if (dmgeqs.length > 1) dm = "(+" + (dmgeqs.length - 1) + ")";//+how many other eq damaged
}
this.$setData("combatDmgEq", dmg);
this.$setData("combatDEqNum", b, this.$DW);
if (dmg.length > 0) dmg = this.$AlignedText("Damaged: " + dmg, dm);
if (ceq) { //if CombatMFD equipment is ok then show the result in MFD
this.$combat_MFD = this.$AlignedText(ep, en) + "\n" + //1.line
sh + "\n" + //2.line
this.$AlignedText(ps, sp + tm) + "\n" + //3.line
dmg + "\n" + //4.line
target + "\n" + //5.-9.lines
this.$TelescopeLine; //10.line
_p.setMultiFunctionText(this.name, this.$combat_MFD, false);
}
//extra data sources (not in MFD)
//altimeter
var c = system.sun; //closest planetary object
if (c) var d = _p.position.distanceTo(c.position);
else var d = 100000000000000000000.0; //10^20m for sure
var l = system.planets;
var len = l.length;
for (var i = 0; i < len; i++) { //find the smallest distance
var s = pp.distanceTo(l[i].position) - l[i].radius;
if (d > s) {
d = s;
c = l[i];
}
}
var alt = ""; //clear if no planetary object
var altr = "";
if (c) {
alt = pp.distanceTo(c) - c.radius - _p.collisionRadius;
altr = Math.round(100 * alt / c.radius) / 100; //how many radius far
if (alt >= 1000000000) alt = Math.floor(alt / 1000000000) + "Mkm";
else if (alt >= 1000) alt = Math.floor(alt / 1000) + "km";
else alt = alt.toFixed(_decimals) + "m";
}
this.$setData("combatAlt", alt, this.$DW);
this.$setData("combatAltR", altr, this.$DW);
//credits of player
this.$setData("combatCredits", formatCredits(player.credits, true, true), this.$DW);
//cabin temp
var ct = Math.max(Math.round(100 * _p.temperature), 23); //prevent flickering below 23
this.$setData("combatCTemp", ct);
//the newest target detected by Telescope
this.$setData("combatNewTelT", this.$TelescopeLine);
//distance of space compass target
var di = "";
var c = _p.compassTarget;
if (c && c.isValid && c.displayName != "Jump Marker") di = Math.max(0, Math.round(pp.distanceTo(c) - c.collisionRadius - _p.collisionRadius));
if (di >= 1000000000) di = Math.floor(di / 1000000000) + "Mkm";
else if (di >= 1000) di = Math.floor(di / 1000) + "km";
else if (c && c.isValid && c.displayName != "Jump Marker") di += "m";
this.$setData("combatSCTDist", di, this.$DW);
//how filled the cargo bay of player ship
this.$setData("combatCargoBar", _p.cargoSpaceUsed / _p.cargoSpaceCapacity);
//service level bar of player ship
this.$setData("combatSLBar", (_p.serviceLevel - 75) / 25);
}
this.$ForwardPercent = function (current) {
var max = 128;//player.ship.maxForwardShield;
var result = 10 * Math.round(10 * current / max);
return result;
}
this.$AftPercent = function (current) {
var max = 128;//player.ship.maxAftShield;
var result = 10 * Math.round(10 * current / max);
return result;
}
this.$showWormholeInfo = function () { //6s delay before show Wormhole info
this.$InfoTimer2Done = true;
if (this.$InfoTimer2) {
this.$InfoTimer2.stop();
delete this.$InfoTimer2;
}
}
this.$AlignedText = function (left, right) { //insert as many spaces between as fill the line
var width = 14.2;
var space = " ";
left += space;
var t = left + right;
while (defaultFont.measureString(t) < width) {
left += space;
t = left + right;
}
//fine tune with hair spaces - from spara's marketObserver
var hairSpace = String.fromCharCode(31);
while (defaultFont.measureString(t + hairSpace) < width) {
left += hairSpace;
t = left + right;
}
return (t);
}
this.$CenteredText = function (txt, width) { //insert spaces before text to align to center in width
var t = "" + txt; //force to srting, else txt.length is undefined for numbers
var w = width / 2;
// log("combat_MFD", "CT1 "+txt+" "+t.length+" "+w); //debug
while (t && t.length < w) { //for fixed with font in setCustomHUDDial
t = " " + t;
}
return (t);
}
this.$RightText = function (txt, width) { //insert spaces before text to align to right in width
var t = "" + txt; //force to srting, else txt.length is undefined for numbers
while (t && t.length < width) { //for fixed with font in setCustomHUDDial
t = " " + t;
}
return (t);
}
this.$SEELetters = function (letter, max, fw, aft, eq1, eq2, eq3, eq4, eq5, eq6) {
var s = 0; //smaller shield side
var l = 0; //larger shield side
var p = player.ship;
if (eq1 && p.equipmentStatus(eq1) == "EQUIPMENT_DAMAGED" ||
eq2 && p.equipmentStatus(eq2) == "EQUIPMENT_DAMAGED" ||
eq3 && p.equipmentStatus(eq3) == "EQUIPMENT_DAMAGED" ||
eq4 && p.equipmentStatus(eq4) == "EQUIPMENT_DAMAGED" ||
eq5 && p.equipmentStatus(eq5) == "EQUIPMENT_DAMAGED" ||
eq6 && p.equipmentStatus(eq6) == "EQUIPMENT_DAMAGED")
letter = "_"; //damaged
s = Math.round(Math.min(fw, aft) / 128);
l = Math.round(Math.max(fw, aft) / 128);
var r = "";
var t = Math.round(max / 128); //total letters
for (var i = 0; i < t; i++)
if (letter == "_") r += letter; //damaged equipment
else if (i < t - l) r += "-"; //empty bank
else if (i < t - s) r += letter.toLowerCase(); //one side of shield is up only
else r += letter; //both forward and aft shield is up
//log("combat_MFD", letter+": "+max+" "+fw+" "+aft+" "+i+". "+(t-s)+" "+(t-l)+" "+t+" "+r); //debug
return (r);
}
this.$AftShieldFacing = function (ship) { //determine which shield of the target facing to player ship
if (ship.vectorForward.angleTo(ship.position.subtract(player.ship.position)) <= Math.PI / 2)
return (true);
return (false);
}
this.$combatKeyIsExists = function (key) {
if (this.$DataArray.indexOf(key) > -1) return true;
else return false;
}
this.$disableKey = function (combatKey) {
this.$DataShow[combatKey] = false;
}
this.$enableKey = function (combatKey) {
this.$DataShow[combatKey] = true;
}
this.$setData = function (key, v, align) { //align=0:left, >0:center in this width, <0:right
this.$Data[key] = v; //save for external access
var p = player.ship;
if (p.setCustomHUDDial && this.$DataShow[key]) {
if (align > 0) v = this.$CenteredText(v, align); //centered in an align wide box
else if (align < 0) v = this.$RightText(v, -align); //right in a -align wide box
p.setCustomHUDDial(key, v);
}
}
|