mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Fix shield recovery/recharge calculations
This commit is contained in:
@@ -104,6 +104,16 @@ export default class Defence extends TranslatedComponent {
|
||||
return { shieldsdps, armoursdps };
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the recharge rate of the SYS capacitor of a power distributor given pips
|
||||
* @param {Object} pd The power distributor
|
||||
* @param {number} sys The number of pips to SYS
|
||||
* @returns {number} The recharge rate in MJ/s
|
||||
*/
|
||||
_calcSysRechargeRate(pd, sys) {
|
||||
return pd.getSystemsRechargeRate() * Math.pow(sys, 1.1) / Math.pow(4, 1.1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate shield metrics
|
||||
* @param {Object} ship The ship
|
||||
@@ -151,39 +161,55 @@ export default class Defence extends TranslatedComponent {
|
||||
const generatorStrength = Calc.shieldStrength(ship.hullMass, ship.baseShieldStrength, shieldGenerator, 1);
|
||||
const boostersStrength = generatorStrength * boost;
|
||||
|
||||
// Recover time is the time taken to go from 0 to 50%. It includes a 15-second wait before shields start to recover
|
||||
// Note that the shields use the broken regeneration rate to define how much energy goes in to the shields, and the normal
|
||||
// regeneration rate to define how much energy is taken from the SYS capacitor
|
||||
// Recover time is the time taken to go from 0 to 50%. It includes a 16-second wait before shields start to recover
|
||||
const shieldToRecover = (generatorStrength + boostersStrength) / 2;
|
||||
const powerDistributor = ship.standard[4].m;
|
||||
// Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes
|
||||
const capacitorDrain = shieldGenerator.getRegenerationRate() - powerDistributor.getSystemsRechargeRate() * (sys / 4);
|
||||
console.log(`shieldToRecover is ${shieldToRecover}`);
|
||||
console.log(`Regeneration rate is ${shieldGenerator.getRegenerationRate()}`);
|
||||
console.log(`Power distributor recharge is ${powerDistributor.getSystemsRechargeRate() * sys / 4}`);
|
||||
console.log(`capacitor drain is ${capacitorDrain}`);
|
||||
const capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain;
|
||||
const sysRechargeRate = this._calcSysRechargeRate(powerDistributor, sys);
|
||||
|
||||
console.log(`Need to recover ${shieldToRecover}`);
|
||||
console.log(`SYS contains ${powerDistributor.getSystemsCapacity()} and recharges at ${powerDistributor.getSystemsRechargeRate() * (sys / 4)}`);
|
||||
let recover = 15;
|
||||
// Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes
|
||||
// 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration
|
||||
let capacitorDrain = (shieldGenerator.getBrokenRegenerationRate() * 0.6) - sysRechargeRate;
|
||||
let capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain;
|
||||
|
||||
let recover = 16;
|
||||
if (capacitorDrain <= 0 || shieldToRecover < capacitorLifetime * shieldGenerator.getBrokenRegenerationRate()) {
|
||||
// We can recover the entire shield from the capacitor store
|
||||
recover += shieldToRecover / shieldGenerator.getBrokenRegenerationRate();
|
||||
console.log(`We can recover the entire shield before the capacitor drains - takes ${recover}`);
|
||||
} else {
|
||||
// We can recover some of the shield from the capacitor store
|
||||
recover += capacitorLifetime;
|
||||
console.log(`We can recover ${capacitorLifetime * shieldGenerator.getBrokenRegenerationRate()} before capacitor is empty`);
|
||||
console.log(`Sys is ${sys}`);
|
||||
const remainingShieldToRecover = shieldToRecover - capacitorLifetime * shieldGenerator.getBrokenRegenerationRate();
|
||||
if (sys === 0) {
|
||||
// No system pips so will never recover shields
|
||||
console.log(`Cannot recover shields`);
|
||||
recover = Math.Inf;
|
||||
} else {
|
||||
// Recover remaining shields at the rate of the power distributor's recharge
|
||||
recover += remainingShieldToRecover / (powerDistributor.getSystemsRechargeRate() * sys / 4);
|
||||
recover += remainingShieldToRecover / (sysRechargeRate / 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
// Recharge time is the time taken to go from 50% to 100%
|
||||
const shieldToRecharge = (generatorStrength + boostersStrength) / 2;
|
||||
|
||||
// Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes
|
||||
// 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration
|
||||
capacitorDrain = (shieldGenerator.getRegenerationRate() * 0.6) - sysRechargeRate;
|
||||
capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain;
|
||||
|
||||
let recharge = 0;
|
||||
if (capacitorDrain <= 0 || shieldToRecharge < capacitorLifetime * shieldGenerator.getRegenerationRate()) {
|
||||
// We can recharge the entire shield from the capacitor store
|
||||
recharge += shieldToRecharge / shieldGenerator.getRegenerationRate();
|
||||
} else {
|
||||
// We can recharge some of the shield from the capacitor store
|
||||
recharge += capacitorLifetime;
|
||||
const remainingShieldToRecharge = shieldToRecharge - capacitorLifetime * shieldGenerator.getRegenerationRate();
|
||||
if (sys === 0) {
|
||||
// No system pips so will never recharge shields
|
||||
recharge = Math.Inf;
|
||||
} else {
|
||||
// Recharge remaining shields at the rate of the power distributor's recharge
|
||||
recharge += remainingShieldToRecharge / (sysRechargeRate / 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +218,8 @@ console.log(`Cannot recover shields`);
|
||||
boosters: boostersStrength,
|
||||
cells: ship.shieldCells,
|
||||
total: generatorStrength + boostersStrength + ship.shieldCells,
|
||||
recover
|
||||
recover,
|
||||
recharge,
|
||||
};
|
||||
|
||||
// Shield resistances have three components: the shield generator, the shield boosters and the SYS pips.
|
||||
@@ -419,7 +446,6 @@ console.log(`Cannot recover shields`);
|
||||
const effectiveThermalArmour = armour.total / armour.thermal.total;
|
||||
effectiveArmourData.push({ value: Math.round(effectiveThermalArmour), label: translate('thermal') });
|
||||
|
||||
// TODO these aren't updating when HRP metrics are altered (maybe - need to confirm)
|
||||
const armourDamageTakenData = [];
|
||||
armourDamageTakenData.push({ value: Math.round(armour.absolute.total * 100), label: translate('absolute') });
|
||||
armourDamageTakenData.push({ value: Math.round(armour.explosive.total * 100), label: translate('explosive') });
|
||||
@@ -433,9 +459,9 @@ console.log(`Cannot recover shields`);
|
||||
<h2>{translate('shield metrics')}</h2>
|
||||
<br/>
|
||||
<h2 onMouseOver={termtip.bind(null, <div>{shieldTooltipDetails}</div>)} onMouseOut={tooltip.bind(null, null)} className='summary'>{translate('raw shield strength')}<br/>{formats.int(shield.total)}{units.MJ}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_SHIELDS'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_SHIELDS')}<br/>{shielddamage.totalsdps == 0 ? translate('infinity') : formats.time(shield.total / shielddamage.totalsdps)}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECOVER'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECOVER_SHIELDS')}<br/>{formats.time(shield.recover)}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECHARGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')}<br/>{formats.time(ship.calcShieldRecharge())}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_LOSE_SHIELDS'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_LOSE_SHIELDS')}<br/>{shielddamage.totalsdps == 0 ? translate('ever') : formats.time(shield.total / shielddamage.totalsdps)}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECOVER'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECOVER_SHIELDS')}<br/>{shield.recover === Math.Inf ? translate('never') : formats.time(shield.recover)}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SG_RECHARGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_RECHARGE_SHIELDS')}<br/>{shield.recharge === Math.Inf ? translate('never') : formats.time(shield.recharge)}</h2>
|
||||
</div>
|
||||
<div className='group quarter'>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SHIELD_SOURCES'))} onMouseOut={tooltip.bind(null, null)}>{translate('shield sources')}</h2>
|
||||
|
||||
@@ -57,11 +57,11 @@ export default class Movement extends TranslatedComponent {
|
||||
<path d="M342 450l.4 1.5-16.2 10.7-.4-.2-3.5-13 .3-.3L342 450zm-14.3 7.6l7.7-5-9.2-.6 1.5 5.6z"/>
|
||||
|
||||
// Speed
|
||||
<text x="500" y="80" strokeWidth='1'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text>
|
||||
<text x="470" y="30" strokeWidth='1'>{formats.int(ship.calcSpeed(eng, fuel, cargo, boost))}m/s</text>
|
||||
// Pitch
|
||||
<text x="355" y="410" strokeWidth='1'>{formats.int(ship.calcPitch(eng, fuel, cargo, boost))}°/s</text>
|
||||
// Roll
|
||||
<text x="450" y="100" strokeWidth='1'>{formats.int(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text>
|
||||
<text x="450" y="110" strokeWidth='1'>{formats.int(ship.calcRoll(eng, fuel, cargo, boost))}°/s</text>
|
||||
// Yaw
|
||||
<text x="160" y="430" strokeWidth='1'>{formats.int(ship.calcYaw(eng, fuel, cargo, boost))}°/s</text>
|
||||
</svg>
|
||||
|
||||
@@ -24,8 +24,8 @@ export const terms = {
|
||||
PHRASE_NO_BUILDS: 'No builds added to comparison!',
|
||||
PHRASE_NO_RETROCH: 'No Retrofitting changes',
|
||||
PHRASE_SELECT_BUILDS: 'Select builds to compare',
|
||||
PHRASE_SG_RECHARGE: 'Time from 50% to 100% charge',
|
||||
PHRASE_SG_RECOVER: 'Time from 0% to 50% charge',
|
||||
PHRASE_SG_RECHARGE: 'Time from 50% to 100% charge, assuming full SYS capacitor to start with',
|
||||
PHRASE_SG_RECOVER: 'Time from 0% to 50% charge, assuming full SYS capacitor to start with',
|
||||
PHRASE_UNLADEN: 'Ship mass excluding fuel and cargo',
|
||||
PHRASE_UPDATE_RDY: 'Update Available! Click to refresh',
|
||||
PHRASE_ENGAGEMENT_RANGE: 'The distance between your ship and its target',
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
text {
|
||||
stroke: @primary;
|
||||
font-size: 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user