From 7f377d6345f63e8f2f236df0dab91b9d4dd0bb18 Mon Sep 17 00:00:00 2001 From: Cmdr McDonald Date: Sat, 14 Jan 2017 13:10:09 +0000 Subject: [PATCH] Add and use range when calculating weapon effectiveness for damage dealt --- ChangeLog.md | 2 + src/app/components/DamageDealt.jsx | 73 +++++++++++++++++++++++++----- src/app/i18n/en.js | 2 + 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 98a65f5d..9dc62185 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,8 @@ #2.2.9 * Use SSL-enabled server for shortlinks * Add falloff for weapons + * Use falloff when calculating weapon effectiveness in damage dealt + * Add engagement range slider to allow user to see change in weapon effectiveness with range #2.2.8 * Fix issue where filling all internals with cargo racks would include restricted slots diff --git a/src/app/components/DamageDealt.jsx b/src/app/components/DamageDealt.jsx index f11fff69..72961f77 100644 --- a/src/app/components/DamageDealt.jsx +++ b/src/app/components/DamageDealt.jsx @@ -4,6 +4,7 @@ import { Ships } from 'coriolis-data/dist'; import ShipSelector from './ShipSelector'; import { nameComparator } from '../utils/SlotFunctions'; import { CollapseSection, ExpandSection, MountFixed, MountGimballed, MountTurret } from './SvgIcons'; +import Slider from '../components/Slider'; /** * Generates an internationalization friendly weapon comparator that will @@ -66,7 +67,9 @@ export default class DamageDealt extends TranslatedComponent { predicate: 'n', desc: true, against: DamageDealt.DEFAULT_AGAINST, - expanded: false + expanded: false, + range: 0.1667, + maxRange: 6000 }; } @@ -74,7 +77,7 @@ export default class DamageDealt extends TranslatedComponent { * Set the initial weapons state */ componentWillMount() { - const weapons = this._calcWeapons(this.props.ship, this.state.against); + const weapons = this._calcWeapons(this.props.ship, this.state.against, this.state.range * this.state.maxRange); this.setState({ weapons }); } @@ -86,7 +89,7 @@ export default class DamageDealt extends TranslatedComponent { */ componentWillReceiveProps(nextProps, nextContext) { if (nextProps.code != this.props.code) { - const weapons = this._calcWeapons(this.props.ship, this.state.against); + const weapons = this._calcWeapons(this.props.ship, this.state.against, this.state.range * this.state.maxRange); this.setState({ weapons }); } return true; @@ -96,19 +99,37 @@ export default class DamageDealt extends TranslatedComponent { * Calculate the damage dealt by a ship * @param {Object} ship The ship which will deal the damage * @param {Object} against The ship against which damage will be dealt + * @param {Object} range The engagement range * @return {boolean} Returns the per-weapon damage */ - _calcWeapons(ship, against) { - let weapons = []; + _calcWeapons(ship, against, range) { + // Tidy up the range so that it's to 4 decimal places + range = Math.round(10000 * range) / 10000; + let weapons = []; for (let i = 0; i < ship.hardpoints.length; i++) { if (ship.hardpoints[i].m) { const m = ship.hardpoints[i].m; if (m.getDamage() && m.grp !== 'po') { + let dropoff = 1; + if (m.getFalloff()) { + // Calculate the dropoff % due to range + if (range > m.getRange()) { + // Weapon is out of range + dropoff = 0; + } else { + const falloff = m.getFalloff(); + if (range > falloff) { + const dropoffRange = m.getRange() - falloff; + // Assuming straight-line falloff + dropoff = 1 - (range - falloff) / dropoffRange; + } + } + } const classRating = `${m.class}${m.rating}${m.missile ? '/' + m.missile : ''}`; - const effectiveness = m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness; - const effectiveDps = m.getDps() * effectiveness; - const effectiveSDps = m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectiveness : effectiveDps; + const effectiveness = (m.getPiercing() >= against.properties.hardness ? 1 : m.getPiercing() / against.properties.hardness) * dropoff; + const effectiveDps = m.getDps() * effectiveness * dropoff; + const effectiveSDps = (m.getClip() ? (m.getClip() * m.getDps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload()) * effectiveness : effectiveDps) * dropoff; weapons.push({ id: i, mount: m.mount, @@ -210,14 +231,23 @@ export default class DamageDealt extends TranslatedComponent { return rows; } + /** + * Update current range + * @param {number} range Range 0-1 + */ + _rangeChange(range) { + const weapons = this._calcWeapons(this.props.ship, this.state.against, this.state.range * this.state.maxRange); + this.setState({ range, weapons }); + } + /** * Render damage dealt * @return {React.Component} contents */ render() { - const { language, tooltip, termtip } = this.context; - const { formats, translate } = language; - const { expanded } = this.state; + const { language, onWindowResize, sizeRatio, tooltip, termtip } = this.context; + const { formats, translate, units } = language; + const { expanded, maxRange, range } = this.state; const sortOrder = this._sortOrder; const onCollapseExpand = this._onCollapseExpand; @@ -239,6 +269,27 @@ export default class DamageDealt extends TranslatedComponent { {this._renderRows(translate, formats)} + + + + + + + + +
{translate('engagement range')} + + + {formats.f2(range * maxRange / 1000)}{units.km} +
: null } ); diff --git a/src/app/i18n/en.js b/src/app/i18n/en.js index 0d0496de..11ec1786 100644 --- a/src/app/i18n/en.js +++ b/src/app/i18n/en.js @@ -28,6 +28,7 @@ export const terms = { PHRASE_SG_RECOVER: 'Recovery (to 50%) after collapse', 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', HELP_MODIFICATIONS_MENU: 'Click on a number to enter a new value, or drag along the bar for small changes', @@ -123,6 +124,7 @@ export const terms = { 'yaw': 'Yaw', 'internal protection': 'Internal protection', 'external protection': 'External protection', + 'engagement range': 'Engagement range', // Modifications ammo: 'Ammunition maximum',