Scripts/NavalGrid.js |
"use strict";
this.name = "NavalGrid";
this.author = "Dybal";
this.copyright = "2020 Dybal";
this.licence = "CC-BY-NC-SA 4.0";
this.description = "Naval Grid worldscript event handlers and functions";
this.version = "2.0";
this.$relatedEquipment = [
"EQ_ENERGY_GRID",
"EQ_NAVAL_GRID",
"EQ_ENERGY_UNIT",
"EQ_NAVAL_ENERGY_UNIT",
"EQ_SHIELD_BOOSTER",
"EQ_NAVAL_SHIELD_BOOSTER"
];
this.$directEquipment = [
"EQ_ENERGY_GRID",
"EQ_NAVAL_GRID",
];
this.$equipmentRemoval = {
EQ_SELL_ENERGY_GRID: "EQ_ENERGY_GRID",
EQ_SELL_NAVAL_GRID: "EQ_NAVAL_GRID"
};
this.$debug = true;
this.$started = false;
//
// Event Handlers
//
//---------------------------------------------------------------------------------//
this.startUpComplete = function _startUpComplete() {
this.$started = true;
this._ng_player_update("startup");
}
//---------------------------------------------------------------------------------//
this.playerBoughtEquipment = function _playerBoughtEquipment(eqKey) {
var _equipmentRemoval = this.$equipmentRemoval;
if (eqKey in _equipmentRemoval) {
var eq_to_remove = _equipmentRemoval[eqKey];
player.ship.removeEquipment(eqKey);
player.ship.removeEquipment(eq_to_remove);
player.credits += 0.4 * EquipmentInfo.infoForKey(eq_to_remove).price;
}
}
//---------------------------------------------------------------------------------//
this.equipmentAdded = function _equipmentAdded(eqKey) {
// don't alter the player ship's shieldRechargeRate until Oolite Equipment Control has
// initialized its baseline structure at startUp
if (!this.$started) return;
if (this.$relatedEquipment.indexOf(eqKey) >= 0) {
if (this.$directEquipment.indexOf(eqKey) >= 0)
this._ng_player_update(eqKey+" added");
else if (!this.$playerUpdateTimer) {
// delay setup to allow Oolite Equipment Control's equipmentAdded to run first
if (this.$debug) log(this.name, "Delaying action on adding "+eqKey);
this.$playerUpdateTimer = new Timer(this, this._ng_player_update.bind(this, eqKey+" added"), 0);
} else
if (this.$debug) log(this.name, "equipmentAdded "+eqKey+", there is already a timer running");
}
}
//---------------------------------------------------------------------------------//
this.equipmentRemoved = function _equipmentRemoved(eqKey) {
// don't alter the player ship's shieldRechargeRate until Oolite Equipment Control has
// initialized its baseline structure at startUp
if (!this.$started) return;
if (this.$relatedEquipment.indexOf(eqKey) >= 0) {
if (this.$directEquipment.indexOf(eqKey) >= 0)
this._ng_player_update(eqKey+" removed");
else if (!this.$playerUpdateTimer) {
// delay setup to allow Oolite Equipment Control's equipmentRemoved to run first
log(this.name, "Delaying action on removing "+eqKey);
if (this.$debug) this.$playerUpdateTimer = new Timer(this, this._ng_player_update.bind(this, eqKey+" removed"), 0);
} else
if (this.$debug) log(this.name, "equipmentRemoved "+eqKey+", there is already a timer running");
}
};
//
// Functions for OXPs to use
//
//-----------------------------------------------------------------------------------//
// Calculates Shield Recharge Rates based on the ship's original shield recharge rate and the
// shield booster devices installed on the ship.
// Does NOT alter the ship's properties.
this.$ng_calc_booster_recharge = function _ng_calc_booster_recharge(ship) {
var that = _ng_calc_booster_recharge;
var shieldBoosterEqs = (that.shieldBoosterEqs = shieldBoosterEqs || [ "EQ_SHIELD_BOOSTER",
"EQ_NAVAL_SHIELD_BOOSTER",
"EQ_NSHIELDS_NPC_SHIELD_BOOSTER",
"EQ_NSHIELDS_NPC_NAVAL_SHIELD_BOOSTER"
]);
var shieldRecharge = { fwd: 2, aft: 2 };
if (ship.scriptInfo) {
if (ship.scriptInfo.shield_recharge_forward) shield_recharge.fwd = parseInt(ship.scriptInfo.shield_recharge_forward);
if (ship.scriptInfo.shield_recharge_aft) shield_recharge.aft = parseInt(ship.scriptInfo.shield_recharge_aft);
}
var eq, scriptInfo, i = shieldBoosterEqs.length;
while (i--) {
eq = shieldBoosterEqs[i];
if (ship.equipmentStatus(eq) === "EQUIPMENT_OK") {
scriptInfo = EquipmentInfo.infoForKey(eq).scriptInfo;
if (this.$debug) log("NavalGrid", eq+", scriptInfo:"+ JSON.stringify(scriptInfo));
let recharge_boost = parseFloat(scriptInfo.oolite_shield_recharge_multiplier);
shieldRecharge.fwd *= recharge_boost;
shieldRecharge.aft *= recharge_boost;
}
}
if (this.$debug) log("NavalGrid", ship.displayName+", shieldRechargeRate after Boosters: "+shieldRecharge.fwd.toFixed(2)+"/"+shieldRecharge.aft.toFixed(2)+", shields: "+ship.maxForwardShield+"/"+ship.maxAftShield);
return shieldRecharge;
}
//-----------------------------------------------------------------------------------//
// Caculates the updated values for the Shield Recharge Rates based on the Grid equipment installed and functional on the ship.
// Deals only with the Grid effects, all other effects must already be incorporated into the base recharge rates input into this.
// NPC enabled, might be called by N-Shields when setting up NPC's shields.
// Does NOT alter the ship's properties.
// Input:
// ship: reference to the ship object (player or NPC);
// shRechargeRates: object with properties 'fwd' and 'aft', containing the base shield recharge rate (the ship's original
// shield recharge rates plus improvements from shield boosters) ;
// context: string describing the circunstances of the call, for logging purposes;
// Output:
// Object with properties 'fwd' and 'aft' with the updated (original + grid improvements) shield
// recharge rates;
this.$ng_calc_shield_recharge_update = function _ng_update(ship, shRechargeRates, context) {
var ng_switch_max = 0;
var result = {
fwd: shRechargeRates.fwd,
aft: shRechargeRates.aft
};
// find the fraction of the energy "production" that should be earmarked for shields
// based on the type of grid; this doesn't take into account at all the other energy
// consuming equipments installed in the ship (shields have priority!), which could lead
// to energy bank depletion (and ship destruction) if the shields keep being drained faster
// than the improved recharge
if (ship.equipmentStatus("EQ_ENERGY_GRID") === "EQUIPMENT_OK") {
if (ship.equipmentStatus("EQ_ENERGY_UNIT") === "EQUIPMENT_OK")
ng_switch_max = 0.5;
else if (ship.equipmentStatus("EQ_NAVAL_ENERGY_UNIT") === "EQUIPMENT_OK")
// civillian grid shouldn't be able to carry full NEU load to the shields...
// this adds around 20% energy transfer compared to EEU
ng_switch_max = 0.3;
} else if (ship.equipmentStatus("EQ_NAVAL_GRID") === "EQUIPMENT_OK") {
if (ship.equipmentStatus("EQ_ENERGY_UNIT") === "EQUIPMENT_OK" ||
ship.equipmentStatus("EQ_NAVAL_ENERGY_UNIT") === "EQUIPMENT_OK")
ng_switch_max = 0.9;
}
var total_shield_recharge_rate = shRechargeRates.fwd + shRechargeRates.aft;
var available_energy = ship.energyRechargeRate - total_shield_recharge_rate;
if (available_energy > 0) {
// only a part of the available energy "production" can be redirected to shields
available_energy *= ng_switch_max;
// distribute the available energy between the shields proportional to their recharge rates
// shtRechRat = shRechRat + availEnerg*(shRechRat/totalRechRate)
result.fwd *= 1 + (available_energy / total_shield_recharge_rate);
result.aft *= 1 + (available_energy / total_shield_recharge_rate);
}
if (this.$debug) log("NavalGrid", ship.displayName+", shieldRechargeRate, from "+shRechargeRates.fwd.toFixed(2)+"/"+shRechargeRates.aft.toFixed(2)+" to "+result.fwd.toFixed(2)+"/"+result.aft.toFixed(2)+", energyRechargeRate:"+ship.energyRechargeRate.toFixed(2)+", available:"+available_energy.toFixed(2));
return result;
}
//
// Internal functions
//
//-----------------------------------------------------------------------------------//
this._ng_player_update = function _ng_player_update(context) {
if (this.$debug) log(this.name, "Updating player ship for "+context);
var ship = player.ship;
var shieldRechargeRates = this.$ng_calc_booster_recharge(ship);
var result = this.$ng_calc_shield_recharge_update(ship, shieldRechargeRates, context);
ship.forwardShieldRechargeRate = result.fwd;
ship.aftShieldRechargeRate = result.aft;
delete this.$playerUpdateTimer;
}
|