mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Compare commits
40 Commits
dw2
...
feature/ap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
250d79162b | ||
|
|
9fc7e64499 | ||
|
|
6223908020 | ||
|
|
c73dd71953 | ||
|
|
c7062de5e6 | ||
|
|
82132d9141 | ||
|
|
435c1b6d45 | ||
|
|
c5c9abe588 | ||
|
|
363735d36b | ||
|
|
2741e7701b | ||
|
|
3be442ea60 | ||
|
|
34cbeca201 | ||
|
|
b37e73ead6 | ||
|
|
ee775521d6 | ||
|
|
5f84aaef1b | ||
|
|
99ac58d999 | ||
|
|
f128a1e87d | ||
|
|
8c0768b451 | ||
|
|
319307136c | ||
|
|
a498452943 | ||
|
|
fb811faf5e | ||
|
|
1cb88115f6 | ||
|
|
94eec120da | ||
|
|
2457c30b94 | ||
|
|
544e5acaef | ||
|
|
9ab35bbaf9 | ||
|
|
01e1609a9f | ||
|
|
8bed35a8ba | ||
|
|
9f4ae60577 | ||
|
|
a66fa8e83f | ||
|
|
307886d4ae | ||
|
|
3987c4e681 | ||
|
|
e129e1da39 | ||
|
|
8acd32b0fc | ||
|
|
f8f99a5aaa | ||
|
|
70cfa58896 | ||
|
|
56571f9c1f | ||
|
|
4ab376d9ed | ||
|
|
2858ef3e93 | ||
|
|
3215b3942d |
13
.gitlab-ci.yml
Normal file
13
.gitlab-ci.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
image: docker:stable
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
stages:
|
||||
- Build image
|
||||
|
||||
docker build:
|
||||
stage: Build image
|
||||
script:
|
||||
- img build --build-arg branch=$CI_COMMIT_REF_NAME -t edcd/coriolis:$CI_COMMIT_REF_NAME .
|
||||
- echo "$REGISTRY_PASSWORD" | img login --username "$REGISTRY_USER" --password-stdin
|
||||
- img push edcd/coriolis:$CI_COMMIT_REF_NAME
|
||||
24
LICENSE.md
Normal file
24
LICENSE.md
Normal file
@@ -0,0 +1,24 @@
|
||||
All Data and [associated JSON](https://github.com/EDCD/coriolis-data) files are intellectual property and copyright of Frontier Developments plc ('Frontier', 'Frontier Developments') and are subject to their
|
||||
[terms and conditions](https://www.frontierstore.net/terms-and-conditions/).
|
||||
|
||||
The code (Javascript, CSS, HTML, and SVG files only) specificially for Coriolis.io is released under the MIT License.
|
||||
|
||||
Copyright (c) 2015 Coriolis.io, Colin McLeod
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software (Javascript, CSS, HTML, and SVG files only), and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -10,6 +10,8 @@ services:
|
||||
- web
|
||||
labels:
|
||||
- "traefik.docker.network=web"
|
||||
- "traefik.frontend.redirect.regex=^https:\/\/coriolis\.edcd\.io\/(.*)"
|
||||
- "traefik.frontend.redirect.replacement=https://coriolis.io/$1"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.basic.frontend.rule=Host:coriolis.io,coriolis.edcd.io"
|
||||
- "traefik.basic.port=80"
|
||||
@@ -25,6 +27,8 @@ services:
|
||||
labels:
|
||||
- "traefik.docker.network=web"
|
||||
- "traefik.enable=true"
|
||||
- "traefik.frontend.redirect.regex=^https:\/\/beta\.coriolis\.edcd\.io\/(.*)"
|
||||
- "traefik.frontend.redirect.replacement=https://beta.coriolis.io/$1"
|
||||
- "traefik.basic.frontend.rule=Host:beta.coriolis.io,beta.coriolis.edcd.io"
|
||||
- "traefik.basic.port=80"
|
||||
- "traefik.basic.protocol=http"
|
||||
@@ -43,9 +47,6 @@ services:
|
||||
- "traefik.basic.port=80"
|
||||
- "traefik.basic.protocol=http"
|
||||
|
||||
|
||||
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
|
||||
@@ -52,12 +52,12 @@ export default class Defence extends TranslatedComponent {
|
||||
* @return {React.Component} contents
|
||||
*/
|
||||
render() {
|
||||
const { ship, sys, opponentWep } = this.props;
|
||||
const { opponent, sys, opponentWep } = this.props;
|
||||
const { language, tooltip, termtip } = this.context;
|
||||
const { formats, translate, units } = language;
|
||||
const { shield, armour, shielddamage, armourdamage } = this.state;
|
||||
|
||||
const pd = ship.standard[4].m;
|
||||
const pd = opponent.standard[4].m;
|
||||
|
||||
const shieldSourcesData = [];
|
||||
const effectiveShieldData = [];
|
||||
|
||||
@@ -121,7 +121,7 @@ export default class HardpointSlot extends Slot {
|
||||
{m.getShieldBoost() ? <div className={'l'}>+{formats.pct1(m.getShieldBoost())}</div> : null}
|
||||
{m.getAmmo() ? <div
|
||||
className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null}
|
||||
{m.getReload() ? <div className={'l'}>{translate('reload')}: {formats.round(m.getReload())}{u.s}</div> : null}
|
||||
{m.getReload() ? <div className={'l'}>{translate('wep_reload')}: {formats.round(m.getReload())}{u.s}</div> : null}
|
||||
{m.getShotSpeed() ? <div
|
||||
className={'l'}>{translate('shotspeed')}: {formats.int(m.getShotSpeed())}{u.mps}</div> : null}
|
||||
{m.getPiercing() ? <div className={'l'}>{translate('piercing')}: {formats.int(m.getPiercing())}</div> : null}
|
||||
|
||||
@@ -349,7 +349,7 @@ export default class Header extends TranslatedComponent {
|
||||
_getShipsMenu() {
|
||||
let shipList = [];
|
||||
|
||||
for (let s in Ships) {
|
||||
for (let s of this.shipOrder) {
|
||||
shipList.push(<ActiveLink key={s} href={outfitURL(s)} className='block'>{Ships[s].properties.name}</ActiveLink>);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,17 +109,18 @@ export default class ModalShoppingList extends TranslatedComponent {
|
||||
*/
|
||||
sendToEDEng(event) {
|
||||
event.preventDefault();
|
||||
let translate = this.context.language.translate;
|
||||
const target = event.target;
|
||||
target.disabled = this.state.blueprints.length > 0;
|
||||
if (this.state.blueprints.length === 0) {
|
||||
target.innerText = 'No modded components.';
|
||||
target.innerText = translate('No modded components.');
|
||||
target.disabled = true;
|
||||
setTimeout(() => {
|
||||
target.innerText = 'Send to EDEngineer';
|
||||
target.innerText = translate('Send to EDEngineer');
|
||||
target.disabled = false;
|
||||
}, 3000);
|
||||
} else {
|
||||
target.innerText = 'Sending...';
|
||||
target.innerText = translate('Sending...');
|
||||
}
|
||||
let countSent = 0;
|
||||
let countTotal = this.state.blueprints.length;
|
||||
@@ -139,7 +140,7 @@ export default class ModalShoppingList extends TranslatedComponent {
|
||||
countSent++;
|
||||
if (countSent === countTotal) {
|
||||
target.disabled = false;
|
||||
target.innerText = 'Send to EDEngineer';
|
||||
target.innerText = translate('Send to EDEngineer');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -230,32 +231,32 @@ export default class ModalShoppingList extends TranslatedComponent {
|
||||
this.sendToEDEng = this.sendToEDEng.bind(this);
|
||||
return <div className='modal' onClick={ (e) => e.stopPropagation() }>
|
||||
<h2>{translate('PHRASE_SHOPPING_MATS')}</h2>
|
||||
<label>Grade 1 rolls </label>
|
||||
<label>{translate('Grade 1 rolls ')}</label>
|
||||
<input id={1} type={'number'} min={0} defaultValue={this.state.matsPerGrade[1]} onChange={this.changeHandler} />
|
||||
<br/>
|
||||
<label>Grade 2 rolls </label>
|
||||
<label>{translate('Grade 2 rolls ')}</label>
|
||||
<input id={2} type={'number'} min={0} defaultValue={this.state.matsPerGrade[2]} onChange={this.changeHandler} />
|
||||
<br/>
|
||||
<label>Grade 3 rolls </label>
|
||||
<label>{translate('Grade 3 rolls ')}</label>
|
||||
<input id={3} type={'number'} min={0} value={this.state.matsPerGrade[3]} onChange={this.changeHandler} />
|
||||
<br/>
|
||||
<label>Grade 4 rolls </label>
|
||||
<label>{translate('Grade 4 rolls ')}</label>
|
||||
<input id={4} type={'number'} min={0} value={this.state.matsPerGrade[4]} onChange={this.changeHandler} />
|
||||
<br/>
|
||||
<label>Grade 5 rolls </label>
|
||||
<label>{translate('Grade 5 rolls ')}</label>
|
||||
<input id={5} type={'number'} min={0} value={this.state.matsPerGrade[5]} onChange={this.changeHandler} />
|
||||
<div>
|
||||
<textarea className='cb json' readOnly value={this.state.matsList} />
|
||||
</div>
|
||||
<label hidden={!compatible} className={'l cap'}>CMDR Name </label>
|
||||
<label hidden={!compatible} className={'l cap'}>{translate('CMDR Name')}</label>
|
||||
<br/>
|
||||
<select hidden={!compatible} className={'cmdr-select l cap'} onChange={this.cmdrChangeHandler} defaultValue={this.state.cmdrName}>
|
||||
{this.state.cmdrs.map(e => <option key={e}>{e}</option>)}
|
||||
</select>
|
||||
<br/>
|
||||
<p hidden={!this.state.failed} id={'failed'} className={'l'}>Failed to send to EDEngineer (Launch EDEngineer and make sure the API is started then refresh the page.)</p>
|
||||
<p hidden={compatible} id={'browserbad'} className={'l'}>Sending to EDEngineer is not compatible with Firefox's security settings. Please try again with Chrome.</p>
|
||||
<button className={'l cb dismiss cap'} disabled={!!this.state.failed || !compatible} onClick={this.sendToEDEng}>{translate('Send To EDEngineer')}</button>
|
||||
<p hidden={!this.state.failed} id={'failed'} className={'l'}>{translate('PHRASE_FAIL_EDENGINEER')}</p>
|
||||
<p hidden={compatible} id={'browserbad'} className={'l'}>{translate('PHRASE_FIREFOX_EDENGINEER')}</p>
|
||||
<button className={'l cb dismiss cap'} disabled={!!this.state.failed || !compatible} onClick={this.sendToEDEng}>{translate('Send to EDEngineer')}</button>
|
||||
<button className={'r dismiss cap'} onClick={this.context.hideModal}>{translate('close')}</button>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -478,7 +478,7 @@ export default class ModificationsMenu extends TranslatedComponent {
|
||||
<tbody>
|
||||
{ showRolls ?
|
||||
<tr>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: false }) }> { translate('roll') }: </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: false }) }> { translate('mroll') }: </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 0 }) } style={{ cursor: 'pointer' }} onClick={_rollWorst} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_WORST')} onMouseOut={tooltip.bind(null, null)}> { translate('0%') } </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 50 })} style={{ cursor: 'pointer' }} onClick={_rollFifty} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_FIFTY')} onMouseOut={tooltip.bind(null, null)}> { translate('50%') } </td>
|
||||
<td tabIndex="0" className={ cn('section-menu button-inline-menu', { active: blueprintCv === 100 })} style={{ cursor: 'pointer' }} onClick={_rollFull} onKeyDown={ this._keyDown } onMouseOver={termtip.bind(null, 'PHRASE_BLUEPRINT_BEST')} onMouseOut={tooltip.bind(null, null)}> { translate('100%') } </td>
|
||||
|
||||
@@ -174,7 +174,7 @@ export default class OutfittingSubpages extends TranslatedComponent {
|
||||
<th style={{ width:'25%' }} className={cn({ active: tab == 'power' })} onClick={this._showTab.bind(this, 'power')} >{translate('power and costs')}</th>
|
||||
<th style={{ width:'25%' }} className={cn({ active: tab == 'profiles' })} onClick={this._showTab.bind(this, 'profiles')} >{translate('profiles')}</th>
|
||||
<th style={{ width:'25%' }} className={cn({ active: tab == 'offence' })} onClick={this._showTab.bind(this, 'offence')} >{translate('offence')}</th>
|
||||
<th style={{ width:'25%' }} className={cn({ active: tab == 'defence' })} onClick={this._showTab.bind(this, 'defence')} >{translate('defence')}</th>
|
||||
<th style={{ width:'25%' }} className={cn({ active: tab == 'defence' })} onClick={this._showTab.bind(this, 'defence')} >{translate('tab_defence')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
@@ -20,28 +20,16 @@ export default class StandardSlotSection extends SlotSection {
|
||||
super(props, context, 'standard', 'core internal');
|
||||
this._optimizeStandard = this._optimizeStandard.bind(this);
|
||||
this._selectBulkhead = this._selectBulkhead.bind(this);
|
||||
this._showDW2Menu = this._showDW2Menu.bind(this);
|
||||
this._dw2 = this._dw2.bind(this);
|
||||
this.selectedRefId = null;
|
||||
this.firstRefId = 'maxjump';
|
||||
this.lastRefId = 'dw2';
|
||||
this.state = {
|
||||
showDW2: false,
|
||||
DW2Tier: -1,
|
||||
DW2Eng: -1,
|
||||
DW2Role: '',
|
||||
DW2Gfsb: false,
|
||||
DW2Gpp: false,
|
||||
DW2Fighter: false
|
||||
};
|
||||
this.lastRefId = 'racer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle focus if the component updates
|
||||
* @param {Object} prevProps React Component properties
|
||||
*/
|
||||
componentDidUpdate(prevProps) {
|
||||
this._handleSectionFocus(prevProps, this.firstRefId, this.lastRefId);
|
||||
this._handleSectionFocus(prevProps,this.firstRefId, this.lastRefId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,114 +72,6 @@ export default class StandardSlotSection extends SlotSection {
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* DW2 Build
|
||||
*/
|
||||
_dw2() {
|
||||
this.selectedRefId = 'dw2';
|
||||
this.setState({ showDW2: false });
|
||||
ShipRoles.dw2Build(this.props.ship, this.state.DW2Tier, this.state.DW2Eng, this.state.DW2Role, this.state.DW2Gfsb, this.state.DW2Gpp, this.state.DW2Fighter);
|
||||
this.props.ship.updateModificationsString();
|
||||
this.props.onChange();
|
||||
this.props.onCargoChange(this.props.ship.cargoCapacity);
|
||||
this.props.onFuelChange(this.props.ship.fuelCapacity);
|
||||
this._close();
|
||||
}
|
||||
|
||||
_showDW2Menu(translate) {
|
||||
return (
|
||||
<div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||
<div className='select-group cap'>{translate('Tier')}</div>
|
||||
<ul id={'tier'}>
|
||||
<li className={cn({ active: this.state.DW2Tier === 1 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Tier: 1 })} onKeyDown={this._keyDown}
|
||||
>{translate('1 - Max. Jump Range, Unshielded')}</li>
|
||||
<li className={cn({ active: this.state.DW2Tier === 2 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Tier: 2 })} onKeyDown={this._keyDown}
|
||||
>{translate('2 - Max. Jump Range, Minimal Shields')}</li>
|
||||
<li className={cn({ active: this.state.DW2Tier === 3 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Tier: 3 })} onKeyDown={this._keyDown}
|
||||
>{translate('3 - Max. Jump Range, Optimal Shields')}</li>
|
||||
<li className={cn({ active: this.state.DW2Tier === 4 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Tier: 4 })} onKeyDown={this._keyDown}
|
||||
>{translate('4 - Max. Jump Range, Optimal Shields & Thrusters')}</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<div className='select-group cap'>{translate('Engineering Level')}</div>
|
||||
<ul id={'engLevel'}>
|
||||
<li className={cn({ active: this.state.DW2Eng === 1 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Eng: 1 })} onKeyDown={this._keyDown}
|
||||
>{translate('No engineering')}</li>
|
||||
<li className={cn({ active: this.state.DW2Eng === 2 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Eng: 2 })} onKeyDown={this._keyDown}
|
||||
>{translate('Only Felicity Farseer and Elvira Martuuk')}</li>
|
||||
<li className={cn({ active: this.state.DW2Eng === 3 }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Eng: 3 })} onKeyDown={this._keyDown}
|
||||
>{translate('All exploration engineers')}</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<div className='select-group cap'>{translate('Role')}</div>
|
||||
<ul id={'role'}>
|
||||
<li className={cn({ active: this.state.DW2Role === 'exploration' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'exploration' })}
|
||||
onKeyDown={this._keyDown}
|
||||
>{translate('Space exploration')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'surface' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'surface' })}
|
||||
onKeyDown={this._keyDown}
|
||||
>{translate('Surface exploration')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'materialProspector' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'materialProspector' })}
|
||||
onKeyDown={this._keyDown}
|
||||
>{translate('Material prospector')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'propectorMining' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'propectorMining' })}
|
||||
onKeyDown={this._keyDown}
|
||||
>{translate('Prospector/Sapper Miner')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'bigRigMining' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'bigRigMining' })}
|
||||
onKeyDown={this._keyDown}
|
||||
>{translate('Big Rig, full mining')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'fuelRat' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'fuelRat' })} onKeyDown={this._keyDown}
|
||||
>{translate('Fuel Rat')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'mechanic' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'mechanic' })} onKeyDown={this._keyDown}
|
||||
>{translate('Mechanic')}</li>
|
||||
<li className={cn({ active: this.state.DW2Role === 'trucker' }, 'lc')} tabIndex="0"
|
||||
onClick={() => this.setState({ DW2Role: 'trucker' })} onKeyDown={this._keyDown}
|
||||
>{translate('Trucker')}</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<ul>
|
||||
<li className={cn({ active: this.state.DW2Gfsb === true }, 'lc')}
|
||||
onClick={() => this.setState({ DW2Gfsb: this.state.DW2Gfsb !== true })}>
|
||||
Add Guardian FSD Booster
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li className={cn({ active: this.state.DW2Gpp === true }, 'lc')}
|
||||
onClick={() => this.setState({ DW2Gpp: this.state.DW2Gpp !== true })}>
|
||||
Add Guardian Power Plant
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li className={cn({ active: this.state.DW2Fighter === true }, 'lc')}
|
||||
onClick={() => this.setState({ DW2Fighter: this.state.DW2Fighter !== true })}>
|
||||
Add Fighter
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<ul>
|
||||
<li onClick={this._dw2} className={cn('lc')} tabIndex="0"
|
||||
onKeyDown={this._keyDown}>
|
||||
<button className="button">Apply</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Miner Build
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
@@ -297,6 +177,7 @@ export default class StandardSlotSection extends SlotSection {
|
||||
warning={m => m instanceof Module ? m.getMaxMass() < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass) : m.maxmass < (ship.unladenMass + cargo + fuel - st[1].m.mass + m.mass)}
|
||||
/>;
|
||||
|
||||
|
||||
slots[3] = <StandardSlot
|
||||
key='fsd'
|
||||
slot={st[2]}
|
||||
@@ -351,7 +232,7 @@ export default class StandardSlotSection extends SlotSection {
|
||||
selected={currentMenu == st[6]}
|
||||
onChange={this.props.onChange}
|
||||
ship={ship}
|
||||
warning={m => m.fuel < st[2].m.maxfuel} // Show warning when fuel tank is smaller than FSD Max Fuel
|
||||
warning= {m => m.fuel < st[2].m.maxfuel} // Show warning when fuel tank is smaller than FSD Max Fuel
|
||||
/>;
|
||||
|
||||
return slots;
|
||||
@@ -364,34 +245,19 @@ export default class StandardSlotSection extends SlotSection {
|
||||
*/
|
||||
_getSectionMenu(translate) {
|
||||
let planetaryDisabled = this.props.ship.internal.length < 4;
|
||||
if (this.state.showDW2 === true) {
|
||||
return this._showDW2Menu(translate);
|
||||
}
|
||||
return <div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||
<ul>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeStandard} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['maxjump'] = smRef}>{translate('Maximize Jump Range')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeStandard} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['maxjump'] = smRef}>{translate('Maximize Jump Range')}</li>
|
||||
</ul>
|
||||
<div className='select-group cap'>{translate('roles')}</div>
|
||||
<ul>
|
||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, false, 0)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['multipurpose'] = smRef}>{translate('Multi-purpose')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, true, 2)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['combat'] = smRef}>{translate('Combat')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeCargo.bind(this, true)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['trader'] = smRef}>{translate('Trader')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeExplorer.bind(this, false)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['explorer'] = smRef}>{translate('Explorer')}</li>
|
||||
<li className={cn('lc', { disabled: planetaryDisabled })} tabIndex={planetaryDisabled ? '' : '0'}
|
||||
onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['planetary'] = smRef}>{translate('Planetary Explorer')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeMiner.bind(this, true)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['miner'] = smRef}>{translate('Miner')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeRacer.bind(this)} onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['racer'] = smRef}>{translate('Racer')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={() => this.setState({ showDW2: !this.state.showDW2 })}
|
||||
onKeyDown={this._keyDown}
|
||||
ref={smRef => this.sectionRefArr['dw2'] = smRef}>{translate('DW2')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, false, 0)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['multipurpose'] = smRef}>{translate('Multi-purpose')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._multiPurpose.bind(this, true, 2)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['combat'] = smRef}>{translate('Combat')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeCargo.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['trader'] = smRef}>{translate('Trader')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeExplorer.bind(this, false)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['explorer'] = smRef}>{translate('Explorer')}</li>
|
||||
<li className={cn('lc', { disabled: planetaryDisabled })} tabIndex={planetaryDisabled ? '' : '0'} onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['planetary'] = smRef}>{translate('Planetary Explorer')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeMiner.bind(this, true)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['miner'] = smRef}>{translate('Miner')}</li>
|
||||
<li className='lc' tabIndex="0" onClick={this._optimizeRacer.bind(this)} onKeyDown={this._keyDown} ref={smRef => this.sectionRefArr['racer'] = smRef}>{translate('Racer')}</li>
|
||||
</ul>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,12 @@ import * as IT from './it';
|
||||
import * as RU from './ru';
|
||||
import * as PL from './pl';
|
||||
import * as PT from './pt';
|
||||
import * as CN from './cn';
|
||||
import * as d3 from 'd3';
|
||||
|
||||
const owofy = require("owofy");
|
||||
|
||||
|
||||
let fallbackTerms = EN.terms;
|
||||
|
||||
/**
|
||||
@@ -27,6 +31,7 @@ export function getLanguage(langCode) {
|
||||
case 'ru': lang = RU; break;
|
||||
case 'pl': lang = PL; break;
|
||||
case 'pt': lang = PT; break;
|
||||
case 'cn': lang = CN; break;
|
||||
default:
|
||||
lang = EN;
|
||||
}
|
||||
@@ -37,7 +42,14 @@ export function getLanguage(langCode) {
|
||||
const round = function(x, n) { const ten_n = Math.pow(10,n); return Math.round(x * ten_n) / ten_n; };
|
||||
|
||||
if(lang === EN) {
|
||||
translate = (t, x) => { return currentTerms[t + '_' + x] || currentTerms[t] || t; };
|
||||
translate = (t, x) => {
|
||||
if (currentTerms[t + '_' + x]) {
|
||||
return owofy(currentTerms[t + '_' + x])
|
||||
} else if (currentTerms[t]) {
|
||||
return owofy(currentTerms[t])
|
||||
}
|
||||
return t;
|
||||
};
|
||||
} else {
|
||||
translate = (t, x) => { return currentTerms[t + '_' + x] || currentTerms[t] || fallbackTerms[t + '_' + x] || fallbackTerms[t] || t; };
|
||||
}
|
||||
@@ -94,5 +106,6 @@ export const Languages = {
|
||||
fr: 'Français',
|
||||
ru: 'ру́сский',
|
||||
pl: 'polski',
|
||||
pt: 'português'
|
||||
pt: 'português',
|
||||
cn: '中文'
|
||||
};
|
||||
|
||||
16
src/app/i18n/cn.js
Normal file
16
src/app/i18n/cn.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const formats = {
|
||||
decimal: '.',
|
||||
thousands: ',',
|
||||
grouping: [3],
|
||||
currency: ['¥', ''],
|
||||
dateTime: '%a %b %e %X %Y',
|
||||
date: '%Y年%m月%d日',
|
||||
time: '%H:%M:%S',
|
||||
periods: ['AM', 'PM'],
|
||||
days: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
|
||||
shortDays: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
|
||||
shortMonths: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
|
||||
};
|
||||
|
||||
export { default as terms } from './cn.json';
|
||||
405
src/app/i18n/cn.json
Normal file
405
src/app/i18n/cn.json
Normal file
File diff suppressed because one or more lines are too long
@@ -81,6 +81,8 @@
|
||||
"TT_SUMMARY_UNLADEN_TOTAL_JUMP": "Farthest possible range with no cargo, a full fuel tank, and jumping as far as possible each time",
|
||||
"TT_SUMMARY_LADEN_TOTAL_JUMP": "Farthest possible range with full cargo, a full fuel tank, and jumping as far as possible each time",
|
||||
"HELP_MODIFICATIONS_MENU": "Click on a number to enter a new value, or drag along the bar for small changes",
|
||||
"PHRASE_FAIL_EDENGINEER": "Failed to send to EDEngineer (Launch EDEngineer and make sure the API is started then refresh the page.)",
|
||||
"PHRASE_FIREFOX_EDENGINEER": "Sending to EDEngineer is not compatible with Firefox's security settings. Please try again with Chrome.",
|
||||
"am": "Auto Field-Maintenance Unit",
|
||||
"bh": "Bulkheads",
|
||||
"bl": "Beam Laser",
|
||||
@@ -172,6 +174,7 @@
|
||||
"ammunition": "Ammo",
|
||||
"secs": "s",
|
||||
"rebuildsperbay": "Rebuilds per bay",
|
||||
"mroll": "Roll",
|
||||
"worst": "Worst",
|
||||
"average": "Average",
|
||||
"random": "Random",
|
||||
@@ -320,6 +323,7 @@
|
||||
"never": "never",
|
||||
"stock": "stock",
|
||||
"boost": "boost",
|
||||
"tab_defence": "defence",
|
||||
"federation rank 1": "Recruit",
|
||||
"federation rank 2": "Cadet",
|
||||
"federation rank 3": "Midshipman",
|
||||
|
||||
@@ -6,6 +6,7 @@ import Ship from '../shipyard/Ship';
|
||||
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||
import { SizeMap } from '../shipyard/Constants';
|
||||
import Link from '../components/Link';
|
||||
const owofy = require("owofy");
|
||||
|
||||
/**
|
||||
* Counts the hardpoints by class/size
|
||||
@@ -177,13 +178,13 @@ export default class ShipyardPage extends Page {
|
||||
return (
|
||||
<tr
|
||||
key={s.id}
|
||||
style={{ height: '1.5em' }}
|
||||
style={{ height: "1.5em" }}
|
||||
className={cn({
|
||||
highlighted: noTouch && this.state.shipId === s.id,
|
||||
highlighted: noTouch && this.state.shipId === s.id
|
||||
})}
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className="ri">{s.manufacturer}</td>
|
||||
<td className="ri">{owofy(s.manufacturer)}</td>
|
||||
<td className="ri">{fInt(s.retailCost)}</td>
|
||||
<td className="ri cap">{translate(SizeMap[s.class])}</td>
|
||||
<td className="ri">{fInt(s.crew)}</td>
|
||||
@@ -302,13 +303,12 @@ export default class ShipyardPage extends Page {
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className="le">
|
||||
<Link href={'/outfit/' + s.id}>{s.name} {s.beta === true ? '(Beta)' : null}</Link>
|
||||
<Link href={'/outfit/' + s.id}>{owofy(s.name)} {s.beta === true ? '(Beta)' : null}</Link>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
i++;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="page" style={{ fontSize: sizeRatio + 'em' }}>
|
||||
<div
|
||||
@@ -595,6 +595,7 @@ export default class ShipyardPage extends Page {
|
||||
{detailRows}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -167,7 +167,7 @@ export default class Module {
|
||||
} else if (name === 'shieldboost' || name === 'hullboost') {
|
||||
modValue = (1 + value) / (1 + baseValue) - 1;
|
||||
} else { // multiplicative
|
||||
modValue = value / baseValue - 1;
|
||||
modValue = baseValue == 0 ? 0 : value / baseValue - 1;
|
||||
}
|
||||
|
||||
if (modification.type === 'percentage') {
|
||||
@@ -703,8 +703,7 @@ export default class Module {
|
||||
let result = 0;
|
||||
if (this['maxmass']) {
|
||||
result = this['maxmass'];
|
||||
// max mass is only modified for non-shield boosters
|
||||
if (result && modified && this.grp !== 'sg') {
|
||||
if (result && modified) {
|
||||
let mult = this.getModValue('optmass') / 10000;
|
||||
if (mult) { result = result * (1 + mult); }
|
||||
}
|
||||
|
||||
@@ -164,13 +164,13 @@ export default class ModuleSet {
|
||||
/**
|
||||
* Finds the lightest usable Shield Generator
|
||||
* @param {number} hullMass Ship hull mass
|
||||
* @param {string} rating The optional rating of the shield
|
||||
* @return {Object} Shield Generator
|
||||
* @return {Object} Thruster
|
||||
*/
|
||||
lightestShieldGenerator(hullMass, rating) {
|
||||
lightestShieldGenerator(hullMass) {
|
||||
let sg = this.internal.sg[0];
|
||||
|
||||
for (let s of this.internal.sg) {
|
||||
if ((!rating || rating === s.rating) && s.mass <= sg.mass && s.maxmass > hullMass) {
|
||||
if (s.mass < sg.mass && s.maxmass > hullMass) {
|
||||
sg = s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1308,7 +1308,7 @@ export default class Ship {
|
||||
let fsd = this.standard[2].m; // Frame Shift Drive;
|
||||
let { unladenMass, fuelCapacity } = this;
|
||||
this.unladenRange = this.calcUnladenRange(); // Includes fuel weight for jump
|
||||
this.fullTankRange = Calc.jumpRange(unladenMass + fuelCapacity, fsd, this); // Full Tank
|
||||
this.fullTankRange = Calc.jumpRange(unladenMass + fuelCapacity, fsd, fuelCapacity, this); // Full Tank
|
||||
this.ladenRange = this.calcLadenRange(); // Includes full tank and caro
|
||||
this.unladenFastestRange = Calc.totalJumpRange(unladenMass + this.fuelCapacity, fsd, fuelCapacity, this);
|
||||
this.ladenFastestRange = Calc.totalJumpRange(unladenMass + this.fuelCapacity + this.cargoCapacity, fsd, fuelCapacity, this);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
import { canMount } from '../utils/SlotFunctions';
|
||||
import { getBlueprint, setPercent } from '../utils/BlueprintFunctions';
|
||||
|
||||
/**
|
||||
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
||||
@@ -16,7 +14,7 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
.useBulkhead(bulkheadIndex);
|
||||
|
||||
if (shielded) {
|
||||
ship.internal.some(function (slot) {
|
||||
ship.internal.some(function(slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, true);
|
||||
@@ -26,577 +24,6 @@ export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Distant Worlds 2 role
|
||||
* Tiers:
|
||||
* 1- Max. Jump Range, Unshielded
|
||||
* 2- Max. Jump Range, Minimal Shields
|
||||
* 3- Max. Jump Range, Optimal Shields
|
||||
* 4- Max. Jump Range, Optimal Shields & Thrusters
|
||||
*
|
||||
* Engineering level:
|
||||
* No engineering
|
||||
* Only Felicity Farseer and Elvira Martuuk
|
||||
* All exploration related engineers
|
||||
*
|
||||
* Role
|
||||
* Exploration
|
||||
* Surface exploration
|
||||
* Big Rig, full mining
|
||||
* Saper / Prospector mining
|
||||
* Fuel rat
|
||||
* Repair rat
|
||||
* Mechanic
|
||||
* Trucker
|
||||
*
|
||||
* @param ship {Ship} Ship instance
|
||||
* @param tier {Number}
|
||||
* @param engineeringLevel {Number}
|
||||
* @param role {String}
|
||||
* @param gfsb {Boolean} add Guardian FSD Booster
|
||||
* @param gpp {Boolean} add Guardian Power Plant
|
||||
* @param fighter {Boolean} add fighter if supported
|
||||
*/
|
||||
export function dw2Build(ship, tier, engineeringLevel, role, gfsb, gpp, fighter) {
|
||||
ship
|
||||
.emptyInternal()
|
||||
.emptyHardpoints()
|
||||
.emptyUtility();
|
||||
const fsd = ModuleUtils.findStandard('fsd', ship.standard[2].maxClass, 'A');
|
||||
ship.use(ship.standard[2], fsd);
|
||||
ship.use(ship.standard[3], ModuleUtils.findStandard('ls', ship.standard[3].maxClass, 'D'));
|
||||
ship.use(ship.standard[4], ModuleUtils.findStandard('pd', 1, 'D'));
|
||||
ship.use(ship.standard[5], ModuleUtils.findStandard('s', ship.standard[5].maxClass, 'D'));
|
||||
const fuelNeeded = ship.standard[2].m.maxfuel * 2;
|
||||
const fuelTank = ship.availCS.standard[6]
|
||||
.filter(e => e.fuel)
|
||||
.filter(e => e.fuel >= fuelNeeded);
|
||||
ship.use(ship.standard[6], fuelTank[0]);
|
||||
ship.useBulkhead(0, false);
|
||||
if (engineeringLevel === 2) {
|
||||
const bp = getBlueprint('FSD_LongRange', ship.standard[2]);
|
||||
bp.grade = 5;
|
||||
bp.special = Modifications.specials['special_fsd_heavy'];
|
||||
ship.standard[2].m.blueprint = bp;
|
||||
setPercent(ship, ship.standard[2].m, 100);
|
||||
// Sensors G3 LW
|
||||
const sBP = getBlueprint('Sensor_Sensor_LightWeight', ship.standard[5]);
|
||||
sBP.grade = 3;
|
||||
ship.standard[5].m.blueprint = sBP;
|
||||
setPercent(ship, ship.standard[5].m, 100);
|
||||
} else if (engineeringLevel === 3) {
|
||||
// Armour G5 HD + Deep Plating
|
||||
const armourBP = getBlueprint('Armour_HeavyDuty', ship.bulkheads);
|
||||
armourBP.grade = 5;
|
||||
armourBP.special = Modifications.specials['special_armour_chunky'];
|
||||
ship.bulkheads.m.blueprint = armourBP;
|
||||
setPercent(ship, ship.bulkheads.m, 100);
|
||||
// FSD G5 IR + Mass Manager
|
||||
const fsdBP = getBlueprint('FSD_LongRange', ship.standard[2]);
|
||||
fsdBP.grade = 5;
|
||||
fsdBP.special = Modifications.specials['special_fsd_heavy'];
|
||||
ship.standard[2].m.blueprint = fsdBP;
|
||||
setPercent(ship, ship.standard[2].m, 100);
|
||||
// LS G4 LW
|
||||
const lsBP = getBlueprint('LifeSupport_LightWeight', ship.standard[3]);
|
||||
lsBP.grade = 4;
|
||||
ship.standard[3].m.blueprint = lsBP;
|
||||
setPercent(ship, ship.standard[3].m, 100);
|
||||
// Sensors G5 LW
|
||||
const sBP = getBlueprint('Sensor_Sensor_LightWeight', ship.standard[5]);
|
||||
sBP.grade = 5;
|
||||
ship.standard[5].m.blueprint = sBP;
|
||||
setPercent(ship, ship.standard[5].m, 100);
|
||||
}
|
||||
|
||||
if (ship.id === 'imperial_clipper') {
|
||||
const fs = ModuleUtils.findInternal('fs', 4, 'A');
|
||||
const slot = ship.internal.filter(a => a.maxClass === 4)[0];
|
||||
ship.use(slot, fs);
|
||||
} else if (ship.id === 'imperial_cutter') {
|
||||
const fs = ModuleUtils.findInternal('fs', 6, 'A');
|
||||
const slot = ship.internal.filter(a => a.maxClass === 6)[0];
|
||||
ship.use(slot, fs);
|
||||
} else if (fsd.class === 2 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 2, 'A');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 2).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 1, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 1)[0];
|
||||
ship.use(slot, fs);
|
||||
} else {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else if (fsd.class === 3 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 3, 'B');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 3).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 2, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 2)[0];
|
||||
ship.use(slot, fs);
|
||||
} else {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else if (fsd.class === 4 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 4, 'b');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 4).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 3, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 3)[0];
|
||||
ship.use(slot, fs);
|
||||
} else {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else if (fsd.class === 5 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 5, 'B');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 5).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 4, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 4).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else {
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
}
|
||||
} else if (fsd.class === 6 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 6, 'B');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 6)
|
||||
.filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 5, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 5)[0];
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else {
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
}
|
||||
} else if (fsd.class === 7 && fsd.rating === 'A') {
|
||||
let fs = ModuleUtils.findInternal('fs', 7, 'B');
|
||||
let slot = ship.internal.filter(a => a.maxClass >= 7).filter(a => a.maxClass >= fs.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (slot && slot.m) {
|
||||
fs = ModuleUtils.findInternal('fs', 6, 'A');
|
||||
slot = ship.internal.filter(a => a.maxClass === 6)[0];
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
} else {
|
||||
if (fs) {
|
||||
ship.use(slot, fs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tier !== 1) {
|
||||
const fuelNeeded = ship.standard[2].m.maxfuel * 3;
|
||||
const fuelTank = ship.availCS.standard[6]
|
||||
.filter(e => e.fuel)
|
||||
.filter(e => e.fuel >= fuelNeeded);
|
||||
if (fuelTank[0]) {
|
||||
ship.use(ship.standard[6], fuelTank[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (tier === 2) {
|
||||
if (ship.id === 'alliance_chieftain' || ship.id === 'alliance_crusader' || ship.id === 'federal_gunship' || ship.id === 'vulture') {
|
||||
const hrp = ModuleUtils.findInternal('hrp', 3, 'D');
|
||||
const slot = ship.internal.filter(e => e.eligible && e.maxClass === 3);
|
||||
if (hrp) {
|
||||
ship.use(slot, hrp);
|
||||
}
|
||||
} else {
|
||||
const sg = ship.getAvailableModules().lightestShieldGenerator(ship.ladenMass);
|
||||
const slot = ship.internal.filter(a => !a.m)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (sg) {
|
||||
ship.use(slot, sg);
|
||||
}
|
||||
if (engineeringLevel === 2) {
|
||||
// ELP G3
|
||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
||||
shieldBP.grade = 3;
|
||||
ship.findShieldGenerator().blueprint = shieldBP;
|
||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
||||
} else if (engineeringLevel === 3) {
|
||||
// ELP G5
|
||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
||||
shieldBP.grade = 5;
|
||||
ship.findShieldGenerator().blueprint = shieldBP;
|
||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
||||
}
|
||||
// const shieldOrder = [1, 2, 3, 4, 5, 6, 7, 8].reverse();
|
||||
// const shieldInternals = ship.internal.filter(a => !a.m)
|
||||
// .filter(a => (!a.eligible) || a.eligible.sg)
|
||||
// .filter(a => a.maxClass >= sg.class)
|
||||
// .sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
// for (let i = 0; i < shieldInternals.length; i++) {
|
||||
// if (canMount(ship, shieldInternals[i], 'sg')) {
|
||||
// ship.use(shieldInternals[i], sg);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
} else if (tier === 3 || tier === 4) {
|
||||
const sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass, 'A');
|
||||
const slot = ship.internal.filter(a => !a.m)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
if (sg) {
|
||||
ship.use(slot, sg);
|
||||
}
|
||||
if (engineeringLevel === 1) {
|
||||
// ELP G3
|
||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
||||
shieldBP.grade = 3;
|
||||
shieldBP.special = Modifications.specials['special_shield_lightweight'];
|
||||
ship.findShieldGenerator().blueprint = shieldBP;
|
||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
||||
} else if (engineeringLevel === 2) {
|
||||
// ELP G5
|
||||
const shieldBP = getBlueprint('ShieldGenerator_Optimised', ship.findShieldGenerator());
|
||||
shieldBP.grade = 5;
|
||||
shieldBP.special = Modifications.specials['special_shield_lightweight'];
|
||||
ship.findShieldGenerator().blueprint = shieldBP;
|
||||
setPercent(ship, ship.findShieldGenerator(), 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (tier === 4) {
|
||||
let t;
|
||||
if (canMount(ship, ship.standard[1], 't', ship.standard[1].maxClass - 1)) {
|
||||
t = ModuleUtils.findStandard('t', ship.standard[1].maxClass - 1, 'A');
|
||||
} else {
|
||||
t = ModuleUtils.findStandard('t', ship.standard[1].maxClass, 'A');
|
||||
}
|
||||
if (t) {
|
||||
ship.use(ship.standard[1], t);
|
||||
}
|
||||
if (engineeringLevel === 1) {
|
||||
// DD G3
|
||||
const tBP = getBlueprint('Engine_Dirty', ship.standard[1]);
|
||||
tBP.grade = 3;
|
||||
tBP.special = Modifications.specials['special_engine_lightweight'];
|
||||
ship.standard[1].m.blueprint = tBP;
|
||||
setPercent(ship, ship.standard[1].m, 100);
|
||||
} else if (engineeringLevel === 2) {
|
||||
// DD G5
|
||||
const tBP = getBlueprint('Engine_Dirty', ship.standard[1]);
|
||||
tBP.grade = 5;
|
||||
tBP.special = Modifications.specials['special_engine_lightweight'];
|
||||
ship.standard[1].m.blueprint = tBP;
|
||||
setPercent(ship, ship.standard[1].m, 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (tier === 4 || tier === 3) {
|
||||
if (engineeringLevel === 3) {
|
||||
const pd = ship.availCS.standard[4]
|
||||
.filter(d => d.rating === 'D')
|
||||
.filter(d => (d.engcap * 1.728) >= ship.boostEnergy)
|
||||
.sort((a, b) => a.class.toString().localeCompare(b.class.toString()))[0];
|
||||
if (pd) {
|
||||
ship.use(ship.standard[4], pd);
|
||||
}
|
||||
// CE G5
|
||||
const pdBP = getBlueprint('PowerDistributor_HighFrequency', ship.standard[4]);
|
||||
pdBP.grade = 5;
|
||||
pdBP.special = Modifications.specials['special_powerdistributor_capacity'];
|
||||
ship.standard[4].m.blueprint = pdBP;
|
||||
setPercent(ship, ship.standard[4].m, 100);
|
||||
} else {
|
||||
const pd = ship.availCS.standard[4]
|
||||
.filter(d => d.rating === 'D')
|
||||
.sort((a, b) => a.engcap > b.engcap)
|
||||
[0];
|
||||
if (pd) {
|
||||
ship.use(ship.standard[4], pd);
|
||||
}
|
||||
}
|
||||
} else if (tier === 4) {
|
||||
if (engineeringLevel === 3) {
|
||||
const pd = ship.availCS.standard[4]
|
||||
.filter(d => d.rating === 'D')
|
||||
.sort((a, b) => b.class.toString().localeCompare(a.class.toString()))[0];
|
||||
if (pd) {
|
||||
ship.use(ship.standard[4], pd);
|
||||
}
|
||||
// CE G5
|
||||
const pdBP = getBlueprint('PowerDistributor_HighFrequency', ship.standard[4]);
|
||||
pdBP.grade = 5;
|
||||
pdBP.special = Modifications.specials['special_powerdistributor_capacity'];
|
||||
ship.standard[4].m.blueprint = pdBP;
|
||||
setPercent(ship, ship.standard[4].m, 100);
|
||||
} else {
|
||||
const pd = ship.availCS.standard[4]
|
||||
.filter(d => d.rating === 'D')
|
||||
.sort((a, b) => b.class.toString().localeCompare(a.class.toString()))[0];
|
||||
if (pd) {
|
||||
ship.use(ship.standard[4], pd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ship.fighterHangars && fighter) {
|
||||
const slot = ship.internal.filter(s => s.maxClass >= 5 && !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))
|
||||
[0];
|
||||
const mod = ModuleUtils.findInternal('fh', 5, 'D');
|
||||
if (slot && mod) {
|
||||
ship.use(slot, mod);
|
||||
}
|
||||
}
|
||||
|
||||
if (tier === 1) {
|
||||
const pd = ModuleUtils.findStandard('pd', 1, 'D');
|
||||
if (pd) {
|
||||
ship.use(ship.standard[4]);
|
||||
}
|
||||
}
|
||||
|
||||
let dssPriority = 0;
|
||||
let srvPriority = 0;
|
||||
let afmu = true;
|
||||
let cargo = false;
|
||||
let miningLaserPriority = 0;
|
||||
let refinery = false;
|
||||
let collector = false;
|
||||
let prospector = false;
|
||||
let miningTools = false;
|
||||
let refuelLimpets = false;
|
||||
let repairLimpets = false;
|
||||
console.log(role);
|
||||
if (role === 'exploration') {
|
||||
dssPriority = 2;
|
||||
afmu = true;
|
||||
} else if (role === 'surface') {
|
||||
dssPriority = 2;
|
||||
srvPriority = 2;
|
||||
} else if (role === 'materialProspector') {
|
||||
miningLaserPriority = 2;
|
||||
srvPriority = 1;
|
||||
} else if (role === 'propectorMining') {
|
||||
dssPriority = 1;
|
||||
prospector = true;
|
||||
miningLaserPriority = 1;
|
||||
cargo = true;
|
||||
miningTools = true;
|
||||
|
||||
} else if (role === 'bigRigMining') {
|
||||
dssPriority = 1;
|
||||
miningLaserPriority = 2;
|
||||
cargo = true;
|
||||
collector = true;
|
||||
refinery = true;
|
||||
miningTools = true;
|
||||
|
||||
} else if (role === 'fuelRat') {
|
||||
refuelLimpets = true;
|
||||
cargo = true;
|
||||
srvPriority = 1;
|
||||
|
||||
} else if (role === 'mechanic') {
|
||||
repairLimpets = true;
|
||||
cargo = true;
|
||||
srvPriority = 1;
|
||||
} else if (role === 'trucker') {
|
||||
cargo = true;
|
||||
}
|
||||
|
||||
if (dssPriority === 2) {
|
||||
const mod = ModuleUtils.findModule('ss', '2i');
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
console.log(slot);
|
||||
console.log(mod);
|
||||
ship.use(slot, mod);
|
||||
}
|
||||
|
||||
if (srvPriority === 2) {
|
||||
let mod;
|
||||
let slot = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 6)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
if (slot) {
|
||||
mod = ModuleUtils.findModule('pv', 'v2');
|
||||
ship.use(slot, mod);
|
||||
} else if (!slot) {
|
||||
slot = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 4)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
if (slot) {
|
||||
mod = ModuleUtils.findModule('pv', 'v4');
|
||||
ship.use(slot, mod);
|
||||
} else {
|
||||
slot = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 2)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
if (slot) {
|
||||
mod = ModuleUtils.findModule('pv', 'v6');
|
||||
ship.use(slot, mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (cargo === true) {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()))[0];
|
||||
const mod = ModuleUtils.findInternal('cr', slot.maxClass, 'E');
|
||||
ship.use(slot, mod);
|
||||
}
|
||||
|
||||
if (refuelLimpets === true) {
|
||||
const mod = ModuleUtils.findModule('fx', 'F4');
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
ship.use(mod, slot);
|
||||
}
|
||||
|
||||
if (repairLimpets === true) {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
let mod;
|
||||
if (slot.maxClass >= 3) {
|
||||
mod = ModuleUtils.findModule('rpl', '9e');
|
||||
} else {
|
||||
mod = ModuleUtils.findModule('rpl', '9s');
|
||||
}
|
||||
ship.use(mod, slot);
|
||||
}
|
||||
|
||||
if (prospector === true) {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
let mod;
|
||||
if (slot.maxClass >= 3) {
|
||||
mod = ModuleUtils.findModule('pc', 'P9');
|
||||
} else {
|
||||
mod = ModuleUtils.findModule('pc', 'P4');
|
||||
}
|
||||
ship.use(mod, slot);
|
||||
}
|
||||
|
||||
if (collector === true) {
|
||||
const slots = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()));
|
||||
if (slots.length >= 2) {
|
||||
let slot = slots.find(s => s.maxClass >= 5);
|
||||
let mod;
|
||||
if (slot) {
|
||||
mod = ModuleUtils.findInternal('cc', slot.maxClass, 'D');
|
||||
} else if (slots.find(s => s.maxClass <= 4)) {
|
||||
slot = slots.find(s => s.maxClass <= 4);
|
||||
mod = ModuleUtils.findInternal('cc', slot.maxClass, 'D');
|
||||
}
|
||||
ship.use(slot, mod);
|
||||
}
|
||||
}
|
||||
|
||||
if (refinery === true) {
|
||||
const slots = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 4)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
if (slots) {
|
||||
const mod = ModuleUtils.findInternal('rf', 4, 'A');
|
||||
ship.use(slots, mod);
|
||||
} else {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass <= 3)
|
||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()))[0];
|
||||
const mod = ModuleUtils.findInternal('rf', slot.maxClass, 'A');
|
||||
ship.use(slots, mod);
|
||||
}
|
||||
}
|
||||
|
||||
if (dssPriority === 1) {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()))[0];
|
||||
const dss = ModuleUtils.findInternal('ss', 1, 'C')
|
||||
if (slot) {
|
||||
ship.use(slot, dss);
|
||||
}
|
||||
}
|
||||
|
||||
if (srvPriority === 1) {
|
||||
const slot = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 2)
|
||||
.sort((a, b) => a.maxClass.toString().localeCompare(b.maxClass.toString()));
|
||||
if (slot.find(s => s.maxClass >= 4)) {
|
||||
const slot = slot.find(s => s.maxClass >= 4);
|
||||
const srv = ModuleUtils.findInternal('pv', 4, 'G')
|
||||
ship.use(slot, srv);
|
||||
} else if (slot.find(s => s.maxClass >= 2)) {
|
||||
const slot = slot.find(s => s.maxClass >= 2);
|
||||
const srv = ModuleUtils.findInternal('pv', 2, 'G')
|
||||
ship.use(slot, srv);
|
||||
}
|
||||
}
|
||||
|
||||
if (gfsb === true) {
|
||||
const slots = ship.internal.filter(s => !s.m)
|
||||
.filter(s => s.maxClass >= 1)
|
||||
.sort((a, b) => b.maxClass.toString().localeCompare(a.maxClass.toString()));
|
||||
if (slots.find(s => s.maxClass >= 5)) {
|
||||
const mod = ModuleUtils.findInternal('gfsb', 5, 'H');
|
||||
ship.use(slots.find(s => s.maxClass >= 5), mod)
|
||||
} else if (slots.find(s => s.maxClass >= 4)) {
|
||||
const mod = ModuleUtils.findInternal('gfsb', 4, 'H');
|
||||
ship.use(slots.find(s => s.maxClass >= 4), mod)
|
||||
} else if (slots.find(s => s.maxClass >= 3)) {
|
||||
const mod = ModuleUtils.findInternal('gfsb', 3, 'H');
|
||||
ship.use(slots.find(s => s.maxClass >= 3), mod)
|
||||
} else if (slots.find(s => s.maxClass >= 2)) {
|
||||
const mod = ModuleUtils.findInternal('gfsb', 2, 'H');
|
||||
ship.use(slots.find(s => s.maxClass >= 2), mod)
|
||||
} else if (slots.find(s => s.maxClass >= 1)) {
|
||||
const mod = ModuleUtils.findInternal('gfsb', 1, 'H');
|
||||
ship.use(slots.find(s => s.maxClass >= 1), mod)
|
||||
}
|
||||
}
|
||||
|
||||
// const pp = ship.getAvailableModules().lightestPowerPlant(Math.max(ship.powerRetracted, ship.powerDeployed), 'A');
|
||||
// const t = ship.getAvailableModules().lightestThruster(ship.ladenMass);
|
||||
// ship.use(ship.standard[0], pp);
|
||||
// ship.use(ship.standard[1], t);
|
||||
|
||||
// ship.useLightestStandard(standardOpts);
|
||||
ship.updatePowerGenerated()
|
||||
.updatePowerUsed()
|
||||
.recalculateMass()
|
||||
.updateJumpStats()
|
||||
.recalculateShield()
|
||||
.recalculateShieldCells()
|
||||
.recalculateArmour()
|
||||
.recalculateDps()
|
||||
.recalculateEps()
|
||||
.recalculateHps()
|
||||
.updateMovement()
|
||||
.updateModificationsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trader Role
|
||||
* @param {Ship} ship Ship instance
|
||||
@@ -609,7 +36,7 @@ export function trader(ship, shielded, standardOpts) {
|
||||
let sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[1], ModuleUtils.standard(1, ship.standard[1].maxClass + 'D')) // D Power Plant
|
||||
.use(ship.standard[1], ModuleUtils.standard(1, ship.standard[1].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[4], ModuleUtils.standard(4, ship.standard[4].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')); // D Sensors
|
||||
|
||||
@@ -618,7 +45,7 @@ export function trader(ship, shielded, standardOpts) {
|
||||
.filter(a => (!a.eligible) || a.eligible.sg)
|
||||
.filter(a => a.maxClass >= sg.class)
|
||||
.sort((a, b) => shieldOrder.indexOf(a.maxClass) - shieldOrder.indexOf(b.maxClass));
|
||||
shieldInternals.some(function (slot) {
|
||||
shieldInternals.some(function(slot) {
|
||||
if (canMount(ship, slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
const shield = ModuleUtils.findInternal('sg', slot.maxClass, 'A');
|
||||
if (shield && shield.maxmass > ship.hullMass) {
|
||||
@@ -660,11 +87,11 @@ export function trader(ship, shielded, standardOpts) {
|
||||
*/
|
||||
export function explorer(ship, planetary) {
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
if (!planetary) { // Non-planetary explorers don't really need to boost
|
||||
standardOpts.pd = '1D';
|
||||
@@ -789,9 +216,9 @@ export function explorer(ship, planetary) {
|
||||
export function miner(ship, shielded) {
|
||||
shielded = true;
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
miningLaserCount = 2,
|
||||
usedSlots = [],
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
// Cargo hatch should be enabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, true);
|
||||
@@ -842,7 +269,7 @@ export function miner(ship, shielded) {
|
||||
|
||||
// Dual mining lasers of highest possible class; remove anything else
|
||||
const miningLaserOrder = [2, 3, 4, 1, 0];
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function (a, b) {
|
||||
const miningLaserHardpoints = ship.hardpoints.concat().sort(function(a, b) {
|
||||
return miningLaserOrder.indexOf(a.maxClass) - miningLaserOrder.indexOf(b.maxClass);
|
||||
});
|
||||
for (let s of miningLaserHardpoints) {
|
||||
@@ -856,7 +283,7 @@ export function miner(ship, shielded) {
|
||||
|
||||
// Number of collector limpets required to be active is a function of the size of the ship and the power of the lasers
|
||||
const miningLaserDps = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function (a, b) {
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getDps();
|
||||
}, 0);
|
||||
// Find out how many internal slots we have, and their potential cargo size
|
||||
@@ -887,7 +314,7 @@ export function miner(ship, shielded) {
|
||||
|
||||
// Power distributor to power the mining lasers indefinitely
|
||||
const wepRateRequired = ship.hardpoints.filter(h => h.m != null)
|
||||
.reduce(function (a, b) {
|
||||
.reduce(function(a, b) {
|
||||
return a + b.m.getEps();
|
||||
}, 0);
|
||||
standardOpts.pd = ship.getAvailableModules().matchingPowerDist({ weprate: wepRateRequired }).id;
|
||||
@@ -909,9 +336,9 @@ export function miner(ship, shielded) {
|
||||
*/
|
||||
export function racer(ship) {
|
||||
let standardOpts = {},
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
usedSlots = [],
|
||||
sgSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
// Cargo hatch can be disabled
|
||||
ship.setSlotEnabled(ship.cargoHatch, false);
|
||||
|
||||
@@ -1,417 +1,417 @@
|
||||
import React from 'react';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
|
||||
/**
|
||||
* Generate a tooltip with details of a blueprint's specials
|
||||
* @param {Object} translate The translate object
|
||||
* @param {Object} blueprint The blueprint at the required grade
|
||||
* @param {string} grp The group of the module
|
||||
* @param {Object} m The module to compare with
|
||||
* @param {string} specialName The name of the special
|
||||
* @returns {Object} The react components
|
||||
*/
|
||||
export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
||||
const effects = [];
|
||||
if (!blueprint || !blueprint.features) {
|
||||
return undefined;
|
||||
}
|
||||
if (m) {
|
||||
// We also add in any benefits from specials that aren't covered above
|
||||
if (m.blueprint) {
|
||||
for (const feature in Modifications.modifierActions[specialName]) {
|
||||
// if (!blueprint.features[feature] && !m.mods.feature) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
||||
if (featureDef.type === 'percentage') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
|
||||
effects.push(
|
||||
<tr key={feature + '_specialTT'}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
||||
style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table width='100%'>
|
||||
<tbody>
|
||||
{effects}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a tooltip with details of a blueprint's effects
|
||||
* @param {Object} translate The translate object
|
||||
* @param {Object} blueprint The blueprint at the required grade
|
||||
* @param {Array} engineers The engineers supplying this blueprint
|
||||
* @param {string} grp The group of the module
|
||||
* @param {Object} m The module to compare with
|
||||
* @returns {Object} The react components
|
||||
*/
|
||||
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
||||
const effects = [];
|
||||
if (!blueprint || !blueprint.features) {
|
||||
return undefined;
|
||||
}
|
||||
for (const feature in blueprint.features) {
|
||||
const featureIsBeneficial = isBeneficial(feature, blueprint.features[feature]);
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (!featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let lowerBound = blueprint.features[feature][0];
|
||||
let upperBound = blueprint.features[feature][1];
|
||||
if (featureDef.type === 'percentage') {
|
||||
lowerBound = Math.round(lowerBound * 1000) / 10;
|
||||
upperBound = Math.round(upperBound * 1000) / 10;
|
||||
}
|
||||
const lowerIsBeneficial = isValueBeneficial(feature, lowerBound);
|
||||
const upperIsBeneficial = isValueBeneficial(feature, upperBound);
|
||||
if (m) {
|
||||
// We have a module - add in the current value
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||
</tr>
|
||||
);
|
||||
} else {
|
||||
// We do not have a module, no value
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
// Because we have a module add in any benefits that aren't part of the primary blueprint
|
||||
for (const feature in m.mods) {
|
||||
if (!blueprint.features[feature]) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We also add in any benefits from specials that aren't covered above
|
||||
if (m.blueprint && m.blueprint.special) {
|
||||
for (const feature in Modifications.modifierActions[m.blueprint.special.edname]) {
|
||||
if (!blueprint.features[feature] && !m.mods.feature) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let components;
|
||||
if (!m) {
|
||||
components = [];
|
||||
for (const component in blueprint.components) {
|
||||
components.push(
|
||||
<tr key={component}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(component)}</td>
|
||||
<td style={{ textAlign: 'right' }}>{blueprint.components[component]}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let engineersList;
|
||||
if (engineers) {
|
||||
engineersList = [];
|
||||
for (const engineer of engineers) {
|
||||
engineersList.push(
|
||||
<tr key={engineer}>
|
||||
<td style={{ textAlign: 'left' }}>{engineer}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('feature')}</td>
|
||||
<td>{translate('worst')}</td>
|
||||
{m ? <td>{translate('current')}</td> : null }
|
||||
<td>{translate('best')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{effects}
|
||||
</tbody>
|
||||
</table>
|
||||
{ components ? <table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('component')}</td>
|
||||
<td>{translate('amount')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{components}
|
||||
</tbody>
|
||||
</table> : null }
|
||||
{ engineersList ? <table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('engineers')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{engineersList}
|
||||
</tbody>
|
||||
</table> : null }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this blueprint feature beneficial?
|
||||
* @param {string} feature The name of the feature
|
||||
* @param {array} values The value of the feature
|
||||
* @returns {boolean} True if this feature is beneficial
|
||||
*/
|
||||
export function isBeneficial(feature, values) {
|
||||
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
|
||||
if (Modifications.modifications[feature].higherbetter) {
|
||||
return !fact;
|
||||
} else {
|
||||
return fact;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this feature value beneficial?
|
||||
* @param {string} feature The name of the feature
|
||||
* @param {number} value The value of the feature
|
||||
* @returns {boolean} True if this value is beneficial
|
||||
*/
|
||||
export function isValueBeneficial(feature, value) {
|
||||
if (Modifications.modifications[feature].higherbetter) {
|
||||
return value > 0;
|
||||
} else {
|
||||
return value < 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a blueprint with a given name and an optional module
|
||||
* @param {string} name The name of the blueprint
|
||||
* @param {Object} module The module for which to obtain this blueprint
|
||||
* @returns {Object} The matching blueprint
|
||||
*/
|
||||
export function getBlueprint(name, module) {
|
||||
// Start with a copy of the blueprint
|
||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0);
|
||||
const found = Modifications.blueprints[findMod(name)];
|
||||
if (!found || !found.fdname) {
|
||||
return {};
|
||||
}
|
||||
const blueprint = JSON.parse(JSON.stringify(found));
|
||||
return blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'percent' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
* @param {Number} percent The percent to set values to of full.
|
||||
*/
|
||||
export function setPercent(ship, m, percent) {
|
||||
ship.clearModifications(m);
|
||||
// Pick given value as multiplier
|
||||
const mult = percent / 100;
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
let value;
|
||||
if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||
} else {
|
||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||
}
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||
} else {
|
||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||
}
|
||||
}
|
||||
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'random' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
*/
|
||||
export function setRandom(ship, m) {
|
||||
// Pick a single value for our randomness
|
||||
setPercent(ship, m, Math.random() * 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a modification feature value
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
* @param {string} featureName The feature being set
|
||||
* @param {number} value The value being set for the feature
|
||||
*/
|
||||
function _setValue(ship, m, featureName, value) {
|
||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||
ship.setModification(m, featureName, value * 10000);
|
||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||
ship.setModification(m, featureName, value * 100);
|
||||
} else {
|
||||
ship.setModification(m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'percent' primary query
|
||||
* @param {Object} m The module for which to perform the query
|
||||
* @returns {Number} percent The percentage indicator of current applied values.
|
||||
*/
|
||||
export function getPercent(m) {
|
||||
let result = null;
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
if (features[featureName][0] === features[featureName][1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = _getValue(m, featureName);
|
||||
let mult;
|
||||
if (featureName == 'shieldboost') {
|
||||
mult = ((1 + value) * (1 + m.shieldboost)) - 1 - m.shieldboost;
|
||||
} else if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
}
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (result && result != mult) {
|
||||
return null;
|
||||
} else if (result != mult) {
|
||||
result = mult;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a feature value
|
||||
* @param {Object} m The module for which to perform the query
|
||||
* @param {string} featureName The feature being queried
|
||||
* @returns {number} The value of the modification as a %
|
||||
*/
|
||||
function _getValue(m, featureName) {
|
||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||
return m.getModValue(featureName, true) / 10000;
|
||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||
return m.getModValue(featureName, true) / 100;
|
||||
} else {
|
||||
return m.getModValue(featureName, true);
|
||||
}
|
||||
}
|
||||
import React from 'react';
|
||||
import { Modifications } from 'coriolis-data/dist';
|
||||
|
||||
/**
|
||||
* Generate a tooltip with details of a blueprint's specials
|
||||
* @param {Object} translate The translate object
|
||||
* @param {Object} blueprint The blueprint at the required grade
|
||||
* @param {string} grp The group of the module
|
||||
* @param {Object} m The module to compare with
|
||||
* @param {string} specialName The name of the special
|
||||
* @returns {Object} The react components
|
||||
*/
|
||||
export function specialToolTip(translate, blueprint, grp, m, specialName) {
|
||||
const effects = [];
|
||||
if (!blueprint || !blueprint.features) {
|
||||
return undefined;
|
||||
}
|
||||
if (m) {
|
||||
// We also add in any benefits from specials that aren't covered above
|
||||
if (m.blueprint) {
|
||||
for (const feature in Modifications.modifierActions[specialName]) {
|
||||
// if (!blueprint.features[feature] && !m.mods.feature) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature) - m.getModValue(feature, true);
|
||||
if (featureDef.type === 'percentage') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
|
||||
effects.push(
|
||||
<tr key={feature + '_specialTT'}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'}
|
||||
style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table width='100%'>
|
||||
<tbody>
|
||||
{effects}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a tooltip with details of a blueprint's effects
|
||||
* @param {Object} translate The translate object
|
||||
* @param {Object} blueprint The blueprint at the required grade
|
||||
* @param {Array} engineers The engineers supplying this blueprint
|
||||
* @param {string} grp The group of the module
|
||||
* @param {Object} m The module to compare with
|
||||
* @returns {Object} The react components
|
||||
*/
|
||||
export function blueprintTooltip(translate, blueprint, engineers, grp, m) {
|
||||
const effects = [];
|
||||
if (!blueprint || !blueprint.features) {
|
||||
return undefined;
|
||||
}
|
||||
for (const feature in blueprint.features) {
|
||||
const featureIsBeneficial = isBeneficial(feature, blueprint.features[feature]);
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (!featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let lowerBound = blueprint.features[feature][0];
|
||||
let upperBound = blueprint.features[feature][1];
|
||||
if (featureDef.type === 'percentage') {
|
||||
lowerBound = Math.round(lowerBound * 1000) / 10;
|
||||
upperBound = Math.round(upperBound * 1000) / 10;
|
||||
}
|
||||
const lowerIsBeneficial = isValueBeneficial(feature, lowerBound);
|
||||
const upperIsBeneficial = isValueBeneficial(feature, upperBound);
|
||||
if (m) {
|
||||
// We have a module - add in the current value
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||
</tr>
|
||||
);
|
||||
} else {
|
||||
// We do not have a module, no value
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td className={lowerBound === 0 ? '' : lowerIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{lowerBound}{symbol}</td>
|
||||
<td className={upperBound === 0 ? '' : upperIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{upperBound}{symbol}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m) {
|
||||
// Because we have a module add in any benefits that aren't part of the primary blueprint
|
||||
for (const feature in m.mods) {
|
||||
if (!blueprint.features[feature]) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We also add in any benefits from specials that aren't covered above
|
||||
if (m.blueprint && m.blueprint.special) {
|
||||
for (const feature in Modifications.modifierActions[m.blueprint.special.edname]) {
|
||||
if (!blueprint.features[feature] && !m.mods.feature) {
|
||||
const featureDef = Modifications.modifications[feature];
|
||||
if (featureDef && !featureDef.hidden) {
|
||||
let symbol = '';
|
||||
if (feature === 'jitter') {
|
||||
symbol = '°';
|
||||
} else if (featureDef.type === 'percentage') {
|
||||
symbol = '%';
|
||||
}
|
||||
let current = m.getModValue(feature);
|
||||
if (featureDef.type === 'percentage' || featureDef.name === 'burst' || featureDef.name === 'burstrof') {
|
||||
current = Math.round(current / 10) / 10;
|
||||
} else if (featureDef.type === 'numeric') {
|
||||
current /= 100;
|
||||
}
|
||||
const currentIsBeneficial = isValueBeneficial(feature, current);
|
||||
effects.push(
|
||||
<tr key={feature}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(feature, grp)}</td>
|
||||
<td> </td>
|
||||
<td className={current === 0 ? '' : currentIsBeneficial ? 'secondary' : 'warning'} style={{ textAlign: 'right' }}>{current}{symbol}</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let components;
|
||||
if (!m) {
|
||||
components = [];
|
||||
for (const component in blueprint.components) {
|
||||
components.push(
|
||||
<tr key={component}>
|
||||
<td style={{ textAlign: 'left' }}>{translate(component)}</td>
|
||||
<td style={{ textAlign: 'right' }}>{blueprint.components[component]}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let engineersList;
|
||||
if (engineers) {
|
||||
engineersList = [];
|
||||
for (const engineer of engineers) {
|
||||
engineersList.push(
|
||||
<tr key={engineer}>
|
||||
<td style={{ textAlign: 'left' }}>{engineer}</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('feature')}</td>
|
||||
<td>{translate('worst')}</td>
|
||||
{m ? <td>{translate('current')}</td> : null }
|
||||
<td>{translate('best')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{effects}
|
||||
</tbody>
|
||||
</table>
|
||||
{ components ? <table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('component')}</td>
|
||||
<td>{translate('amount')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{components}
|
||||
</tbody>
|
||||
</table> : null }
|
||||
{ engineersList ? <table width='100%'>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{translate('engineers')}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{engineersList}
|
||||
</tbody>
|
||||
</table> : null }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this blueprint feature beneficial?
|
||||
* @param {string} feature The name of the feature
|
||||
* @param {array} values The value of the feature
|
||||
* @returns {boolean} True if this feature is beneficial
|
||||
*/
|
||||
export function isBeneficial(feature, values) {
|
||||
const fact = (values[0] < 0 || (values[0] === 0 && values[1] < 0));
|
||||
if (Modifications.modifications[feature].higherbetter) {
|
||||
return !fact;
|
||||
} else {
|
||||
return fact;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this feature value beneficial?
|
||||
* @param {string} feature The name of the feature
|
||||
* @param {number} value The value of the feature
|
||||
* @returns {boolean} True if this value is beneficial
|
||||
*/
|
||||
export function isValueBeneficial(feature, value) {
|
||||
if (Modifications.modifications[feature].higherbetter) {
|
||||
return value > 0;
|
||||
} else {
|
||||
return value < 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a blueprint with a given name and an optional module
|
||||
* @param {string} name The name of the blueprint
|
||||
* @param {Object} module The module for which to obtain this blueprint
|
||||
* @returns {Object} The matching blueprint
|
||||
*/
|
||||
export function getBlueprint(name, module) {
|
||||
// Start with a copy of the blueprint
|
||||
const findMod = val => Object.keys(Modifications.blueprints).find(elem => elem.toString().toLowerCase().search(val.toString().toLowerCase().replace(/(OutfittingFieldType_|persecond)/igm, '')) >= 0);
|
||||
const found = Modifications.blueprints[findMod(name)];
|
||||
if (!found || !found.fdname) {
|
||||
return {};
|
||||
}
|
||||
const blueprint = JSON.parse(JSON.stringify(found));
|
||||
return blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'percent' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
* @param {Number} percent The percent to set values to of full.
|
||||
*/
|
||||
export function setPercent(ship, m, percent) {
|
||||
ship.clearModifications(m);
|
||||
// Pick given value as multiplier
|
||||
const mult = percent / 100;
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
let value;
|
||||
if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||
} else {
|
||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||
}
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
value = features[featureName][0] + ((features[featureName][1] - features[featureName][0]) * mult);
|
||||
} else {
|
||||
value = features[featureName][1] + ((features[featureName][0] - features[featureName][1]) * mult);
|
||||
}
|
||||
}
|
||||
|
||||
_setValue(ship, m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'random' primary modifications
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
*/
|
||||
export function setRandom(ship, m) {
|
||||
// Pick a single value for our randomness
|
||||
setPercent(ship, m, Math.random() * 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a modification feature value
|
||||
* @param {Object} ship The ship for which to perform the modifications
|
||||
* @param {Object} m The module for which to perform the modifications
|
||||
* @param {string} featureName The feature being set
|
||||
* @param {number} value The value being set for the feature
|
||||
*/
|
||||
function _setValue(ship, m, featureName, value) {
|
||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||
ship.setModification(m, featureName, value * 10000);
|
||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||
ship.setModification(m, featureName, value * 100);
|
||||
} else {
|
||||
ship.setModification(m, featureName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'percent' primary query
|
||||
* @param {Object} m The module for which to perform the query
|
||||
* @returns {Number} percent The percentage indicator of current applied values.
|
||||
*/
|
||||
export function getPercent(m) {
|
||||
let result = null;
|
||||
const features = m.blueprint.grades[m.blueprint.grade].features;
|
||||
for (const featureName in features) {
|
||||
if (features[featureName][0] === features[featureName][1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = _getValue(m, featureName);
|
||||
let mult;
|
||||
if (featureName == 'shieldboost') {
|
||||
mult = ((1 + value) * (1 + m.shieldboost)) - 1 - m.shieldboost;
|
||||
} else if (Modifications.modifications[featureName].higherbetter) {
|
||||
// Higher is better, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
}
|
||||
} else {
|
||||
// Higher is worse, but is this making it better or worse?
|
||||
if (features[featureName][0] < 0 || (features[featureName][0] === 0 && features[featureName][1] < 0)) {
|
||||
mult = Math.round((value - features[featureName][0]) / (features[featureName][1] - features[featureName][0]) * 100);
|
||||
} else {
|
||||
mult = Math.round((value - features[featureName][1]) / (features[featureName][0] - features[featureName][1]) * 100);
|
||||
}
|
||||
}
|
||||
|
||||
if (result && result != mult) {
|
||||
return null;
|
||||
} else if (result != mult) {
|
||||
result = mult;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query a feature value
|
||||
* @param {Object} m The module for which to perform the query
|
||||
* @param {string} featureName The feature being queried
|
||||
* @returns {number} The value of the modification as a %
|
||||
*/
|
||||
function _getValue(m, featureName) {
|
||||
if (Modifications.modifications[featureName].type == 'percentage') {
|
||||
return m.getModValue(featureName, true) / 10000;
|
||||
} else if (Modifications.modifications[featureName].type == 'numeric') {
|
||||
return m.getModValue(featureName, true) / 100;
|
||||
} else {
|
||||
return m.getModValue(featureName, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,11 +145,11 @@ export function diffDetails(language, m, mm) {
|
||||
if (m.grp === 'pp') {
|
||||
let mPowerGeneration = m.pgen || 0;
|
||||
let mmPowerGeneration = mm ? mm.getPowerGeneration() : 0;
|
||||
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MJ}</span></div>);
|
||||
if (mPowerGeneration != mmPowerGeneration) propDiffs.push(<div key='pgen'>{translate('pgen')}: <span className={diffClass(mPowerGeneration, mmPowerGeneration)}>{diff(formats.round, mPowerGeneration, mmPowerGeneration)}{units.MW}</span></div>);
|
||||
} else {
|
||||
let mPowerUsage = m.power || 0;
|
||||
let mmPowerUsage = mm ? mm.getPowerUsage() || 0 : 0;
|
||||
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MJ}</span></div>);
|
||||
if (mPowerUsage != mmPowerUsage) propDiffs.push(<div key='power'>{translate('power')}: <span className={diffClass(mPowerUsage, mmPowerUsage, true)}>{diff(formats.round, mPowerUsage, mmPowerUsage)}{units.MW}</span></div>);
|
||||
}
|
||||
|
||||
let mDps = m.damage * (m.rpshot || 1) * (m.rof || 1);
|
||||
|
||||
61
src/clippy.css
Normal file
61
src/clippy.css
Normal file
@@ -0,0 +1,61 @@
|
||||
.clippy, .clippy-balloon {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clippy-balloon {
|
||||
|
||||
background: #FFC;
|
||||
color: black;
|
||||
padding: 8px;
|
||||
border: 1px solid black;
|
||||
border-radius: 5px;
|
||||
|
||||
}
|
||||
|
||||
.clippy-content {
|
||||
max-width: 200px;
|
||||
min-width: 120px;
|
||||
font-family: "Microsoft Sans", sans-serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.clippy-tip {
|
||||
width: 10px;
|
||||
height: 16px;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAgCAMAAAAlvKiEAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRF///MAAAA////52QwgAAAAAN0Uk5T//8A18oNQQAAAGxJREFUeNqs0kEOwCAIRFHn3//QTUU6xMyyxii+jQosrTPkyPEM6IN3FtzIRk1U4dFeKWQiH6pRRowMVKEmvronEynkwj0uZJgR22+YLopPSo9P34wJSamLSU7lSIWLJU7NkNomNlhqxUeAAQC+TQLZyEuJBwAAAABJRU5ErkJggg==) no-repeat;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.clippy-top-left .clippy-tip {
|
||||
top: 100%;
|
||||
margin-top: 0px;
|
||||
left: 100%;
|
||||
margin-left: -50px;
|
||||
}
|
||||
|
||||
.clippy-top-right .clippy-tip {
|
||||
top: 100%;
|
||||
margin-top: 0px;
|
||||
left: 0;
|
||||
margin-left: 50px;
|
||||
background-position: -10px 0;
|
||||
|
||||
}
|
||||
|
||||
.clippy-bottom-right .clippy-tip {
|
||||
top: 0;
|
||||
margin-top: -16px;
|
||||
left: 0;
|
||||
margin-left: 50px;
|
||||
background-position: -10px -16px;
|
||||
}
|
||||
|
||||
.clippy-bottom-left .clippy-tip {
|
||||
top: 0;
|
||||
margin-top: -16px;
|
||||
left: 100%;
|
||||
margin-left: -50px;
|
||||
background-position: 0px -16px;
|
||||
}
|
||||
1
src/clippy.min.js
vendored
Normal file
1
src/clippy.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
108
src/index.ejs
108
src/index.ejs
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<head>
|
||||
<title>Coriolis EDCD Edition</title>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[0] %>">
|
||||
@@ -13,7 +13,7 @@
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="shortcut icon" href=/favicon2.ico>
|
||||
<link rel="icon" sizes="152x152 192x192" type="image/png"
|
||||
href="/192x192.png">
|
||||
href="/192x192.png">
|
||||
|
||||
<!-- Apple/iOS headers -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
@@ -29,44 +29,74 @@
|
||||
<script>
|
||||
window.CORIOLIS_GAPI_KEY = '<%- htmlWebpackPlugin.options.gapiKey %>';
|
||||
window.CORIOLIS_VERSION = '<%- htmlWebpackPlugin.options.version %>';
|
||||
window.CORIOLIS_DATE = '<%- htmlWebpackPlugin.options.date.toISOString().slice(0, 10) %>';
|
||||
window.BUGSNAG_VERSION = '<%- htmlWebpackPlugin.options.version + '-' + htmlWebpackPlugin.options.date.toISOString() %>';
|
||||
window.CORIOLIS_DATE = '<%- htmlWebpackPlugin.options.date.toISOString().slice(0, 10) %>';
|
||||
window.BUGSNAG_VERSION = '<%- htmlWebpackPlugin.options.version + '-' + htmlWebpackPlugin.options.date.toISOString() %>';
|
||||
</script>
|
||||
<% if (htmlWebpackPlugin.options.uaTracking) { %>
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
ga('create', '<%- htmlWebpackPlugin.options.uaTracking %>', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
<% } %>
|
||||
|
||||
<!-- Piwik -->
|
||||
<!-- <script type="text/javascript">
|
||||
var _paq = _paq || [];
|
||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||
_paq.push(["setCookieDomain", "*.coriolis.edcd.io"]);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//stats.isadankme.me/";
|
||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||
_paq.push(['setSiteId', '4']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script>-->
|
||||
<!-- End Piwik Code -->
|
||||
|
||||
<!-- Bugsnag -->
|
||||
<script src="https://d2wy8f7a9ursnm.cloudfront.net/v5.0.0/bugsnag.min.js"></script>
|
||||
<script>
|
||||
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', {appVersion: window.BUGSNAG_VERSION || undefined})
|
||||
window.Bugsnag = window.bugsnagClient
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color:#000;">
|
||||
<section id="coriolis"></section>
|
||||
window.ga = window.ga || function() {(ga.q = ga.q || []).push(arguments);};
|
||||
ga.l = +new Date;
|
||||
ga('create', '<%- htmlWebpackPlugin.options.uaTracking %>', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
<% } %>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<!-- Piwik -->
|
||||
<!-- <script type="text/javascript">
|
||||
var _paq = _paq || [];
|
||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
||||
_paq.push(["setCookieDomain", "*.coriolis.edcd.io"]);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//stats.isadankme.me/";
|
||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||
_paq.push(['setSiteId', '4']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
</script>-->
|
||||
<!-- End Piwik Code -->
|
||||
|
||||
<!-- Bugsnag -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
|
||||
<script src="https://d2wy8f7a9ursnm.cloudfront.net/v5.0.0/bugsnag.min.js"></script>
|
||||
<script src="/clippy.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
const advice = ['When all else fails, Put a docking computer in every slot. My name is Clippy.',
|
||||
'Fly in a stright line and roll, your evasion increases by 200%!',
|
||||
'Boost!!!',
|
||||
'If you are running out of power, consider deactivating thrusters!',
|
||||
'Make sure to set fire-groups for your SCBs!',
|
||||
'If you find yourself dying often - git gud!',
|
||||
'Remember, shield boosters increase skill!',
|
||||
'Remember, B rated drives offer greater speed!',
|
||||
'Point directly into the jet cone and full throttle for optimal FSD boost.',
|
||||
'Raxxla can only be found in open play.',
|
||||
'Try silent running when under focus to drop aggro, and reboot when your opponents lose sight of you!'];
|
||||
clippy.load('Clippy', function(agent) {
|
||||
// do anything with the loaded agent
|
||||
agent.show();
|
||||
|
||||
setInterval(() => {
|
||||
agent.animate();
|
||||
const toSpeak = advice[Math.random() * advice.length >> 0];
|
||||
agent.speak(toSpeak);
|
||||
}, (20000));
|
||||
setInterval(() => {
|
||||
agent.animate();
|
||||
agent.speak('@everyone FDL. :pray:');
|
||||
}, (69000));
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', { appVersion: window.BUGSNAG_VERSION || undefined });
|
||||
window.Bugsnag = window.bugsnagClient;
|
||||
</script>
|
||||
</head>
|
||||
<body style="background-color:#000;">
|
||||
<section id="coriolis"></section>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -184,3 +184,5 @@ footer {
|
||||
border: 1px @secondary solid;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@import "../../node_modules/clippy.js/build/clippy.css";
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
// Foreground colors
|
||||
@fg: #CCC;
|
||||
@muted: #999;
|
||||
@primary: #FF8C0D; // Light Orange
|
||||
@secondary: #1FB0FF; // Light blue
|
||||
@primary: #e64980; // Light Orange
|
||||
@secondary: #9775fa; // Light blue
|
||||
@warning: #FF3B00; // Dark Orange
|
||||
@disabled: #555; // Light grey
|
||||
@success: #71a052; // Green
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = {
|
||||
publicPath: '/'
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin(['src/.htaccess', 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']),
|
||||
new CopyWebpackPlugin(['src/.htaccess', 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js', 'src/clippy.min.js']),
|
||||
// new webpack.optimize.CommonsChunkPlugin({
|
||||
// name: 'lib',
|
||||
// filename: 'lib.js'
|
||||
|
||||
@@ -32,7 +32,7 @@ module.exports = {
|
||||
from: 'src/images/logo/*',
|
||||
flatten: true,
|
||||
to: ''
|
||||
}, 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']),
|
||||
}, 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js', 'src/clippy.min.js']),
|
||||
// new webpack.optimize.CommonsChunkPlugin({
|
||||
// name: 'lib',
|
||||
// filename: 'lib.[chunkhash:6].js'
|
||||
|
||||
Reference in New Issue
Block a user