├── .DS_Store ├── .gitignore ├── .npmignore ├── .vscode └── settings.json ├── package.json ├── scripts ├── ML │ ├── create_pilot_csv.ts │ ├── create_tournament_csv.ts │ ├── plot_data.json │ ├── require.js │ ├── train.py │ ├── train_lit.py │ └── update_predictions.ts ├── amg │ ├── parser.ts │ ├── pdfParser.ts │ ├── ship_points.pdf │ ├── ship_points_.pdf │ └── upgrade_points.pdf ├── ffg │ ├── process.ts │ ├── scrape.ts │ └── utils.ts ├── ffg2xws.js ├── sirjorj │ ├── Common.ts │ ├── Pilot.ts │ ├── Upgrade.ts │ └── merge.ts └── xwing-data │ ├── data2-types.ts │ └── merge.ts ├── src ├── assets │ ├── colors.ts │ ├── conditions │ │ └── index.ts │ ├── ffg-xws.ts │ ├── index.ts │ ├── pilots │ │ ├── .DS_Store │ │ ├── first-order │ │ │ ├── gozanti-class-cruiser.ts │ │ │ ├── index.ts │ │ │ ├── raider-class-corvette.ts │ │ │ ├── tie-ba-interceptor.ts │ │ │ ├── tie-fo-fighter.ts │ │ │ ├── tie-se-bomber.ts │ │ │ ├── tie-sf-fighter.ts │ │ │ ├── tie-vn-silencer.ts │ │ │ ├── tie-wi-whisper-modified-interceptor.ts │ │ │ ├── upsilon-class-command-shuttle.ts │ │ │ ├── upsilon-class-shuttle.ts │ │ │ └── xi-class-light-shuttle.ts │ │ ├── galactic-empire │ │ │ ├── alpha-class-star-wing.ts │ │ │ ├── gauntlet-fighter.ts │ │ │ ├── gozanti-class-cruiser.ts │ │ │ ├── index.ts │ │ │ ├── lambda-class-t-4a-shuttle.ts │ │ │ ├── raider-class-corvette.ts │ │ │ ├── tie-advanced-v1.ts │ │ │ ├── tie-advanced-x1.ts │ │ │ ├── tie-ag-aggressor.ts │ │ │ ├── tie-ca-punisher.ts │ │ │ ├── tie-d-defender.ts │ │ │ ├── tie-in-interceptor.ts │ │ │ ├── tie-ln-fighter.ts │ │ │ ├── tie-ph-phantom.ts │ │ │ ├── tie-rb-heavy.ts │ │ │ ├── tie-reaper.ts │ │ │ ├── tie-sa-bomber.ts │ │ │ ├── tie-sk-striker.ts │ │ │ └── vt-49-decimator.ts │ │ ├── galactic-republic │ │ │ ├── arc-170-starfighter.ts │ │ │ ├── btl-b-y-wing.ts │ │ │ ├── clone-z-95-headhunter.ts │ │ │ ├── cr90-corellian-corvette.ts │ │ │ ├── delta-7-aethersprite.ts │ │ │ ├── delta-7b-aethersprite.ts │ │ │ ├── eta-2-actis.ts │ │ │ ├── gauntlet-fighter.ts │ │ │ ├── index.ts │ │ │ ├── laat-i-gunship.ts │ │ │ ├── naboo-royal-n-1-starfighter.ts │ │ │ ├── nimbus-class-v-wing.ts │ │ │ ├── syliure-class-hyperspace-ring.ts │ │ │ └── v-19-torrent-starfighter.ts │ │ ├── index.ts │ │ ├── rebel-alliance │ │ │ ├── a-sf-01-b-wing.ts │ │ │ ├── arc-170-starfighter.ts │ │ │ ├── attack-shuttle.ts │ │ │ ├── auzituck-gunship.ts │ │ │ ├── btl-a4-y-wing.ts │ │ │ ├── btl-s8-k-wing.ts │ │ │ ├── cr90-corellian-corvette.ts │ │ │ ├── e-wing.ts │ │ │ ├── fang-fighter.ts │ │ │ ├── gauntlet-fighter.ts │ │ │ ├── gr-75-medium-transport.ts │ │ │ ├── hwk-290-light-freighter.ts │ │ │ ├── index.ts │ │ │ ├── modified-yt-1300-light-freighter.ts │ │ │ ├── rz-1-a-wing.ts │ │ │ ├── sheathipede-class-shuttle.ts │ │ │ ├── t-65-x-wing.ts │ │ │ ├── tie-ln-fighter.ts │ │ │ ├── ut-60d-u-wing.ts │ │ │ ├── vcx-100-light-freighter.ts │ │ │ ├── yt-2400-light-freighter.ts │ │ │ └── z-95-af4-headhunter.ts │ │ ├── resistance │ │ │ ├── bta-nr2-y-wing.ts │ │ │ ├── fireball.ts │ │ │ ├── gr-75-medium-transport.ts │ │ │ ├── index.ts │ │ │ ├── mg-100-starfortress.ts │ │ │ ├── resistance-transport-pod.ts │ │ │ ├── resistance-transport.ts │ │ │ ├── rz-2-a-wing.ts │ │ │ ├── scavenged-yt-1300.ts │ │ │ └── t-70-x-wing.ts │ │ ├── scum-and-villainy │ │ │ ├── aggressor-assault-fighter.ts │ │ │ ├── btl-a4-y-wing.ts │ │ │ ├── c-roc-cruiser.ts │ │ │ ├── customized-yt-1300-light-freighter.ts │ │ │ ├── escape-craft.ts │ │ │ ├── fang-fighter.ts │ │ │ ├── firespray-class-patrol-craft.ts │ │ │ ├── g-1a-starfighter.ts │ │ │ ├── gauntlet-fighter.ts │ │ │ ├── hwk-290-light-freighter.ts │ │ │ ├── index.ts │ │ │ ├── jumpmaster-5000.ts │ │ │ ├── kihraxz-fighter.ts │ │ │ ├── lancer-class-pursuit-craft.ts │ │ │ ├── m12-l-kimogila-fighter.ts │ │ │ ├── m3-a-interceptor.ts │ │ │ ├── modified-tie-ln-fighter.ts │ │ │ ├── quadrijet-transfer-spacetug.ts │ │ │ ├── rogue-class-starfighter.ts │ │ │ ├── scurrg-h-6-bomber.ts │ │ │ ├── st-70-assault-ship.ts │ │ │ ├── starviper-class-attack-platform.ts │ │ │ ├── trident-class-assault-ship.ts │ │ │ ├── yt-2400-light-freighter.ts │ │ │ ├── yv-666-light-freighter.ts │ │ │ └── z-95-af4-headhunter.ts │ │ └── separatist-alliance │ │ │ ├── belbullab-22-starfighter.ts │ │ │ ├── c-roc-cruiser.ts │ │ │ ├── droid-tri-fighter.ts │ │ │ ├── firespray-class-patrol-craft.ts │ │ │ ├── gauntlet-fighter.ts │ │ │ ├── hmp-droid-gunship.ts │ │ │ ├── hyena-class-droid-bomber.ts │ │ │ ├── index.ts │ │ │ ├── nantex-class-starfighter.ts │ │ │ ├── rogue-class-starfighter.ts │ │ │ ├── sith-infiltrator.ts │ │ │ ├── trident-class-assault-ship.ts │ │ │ └── vulture-class-droid-fighter.ts │ ├── sources │ │ ├── additional-pilots.ts │ │ ├── additional-ships.ts │ │ ├── additional-upgrades.ts │ │ ├── core-sets.ts │ │ ├── epic.ts │ │ ├── first-order.ts │ │ ├── galactic-empire.ts │ │ ├── galactic-republic.ts │ │ ├── index.ts │ │ ├── rebel-alliance.ts │ │ ├── resistance.ts │ │ ├── scum-and-villainy.ts │ │ └── separatist-alliance.ts │ └── upgrades │ │ ├── astromech.ts │ │ ├── cannon.ts │ │ ├── cargo.ts │ │ ├── command.ts │ │ ├── configuration.ts │ │ ├── crew.ts │ │ ├── device.ts │ │ ├── force-power.ts │ │ ├── gunner.ts │ │ ├── hardpoint.ts │ │ ├── hyperdrive.ts │ │ ├── illicit.ts │ │ ├── index.ts │ │ ├── missile.ts │ │ ├── modification.ts │ │ ├── sensor.ts │ │ ├── tactical-relay.ts │ │ ├── talent.ts │ │ ├── team.ts │ │ ├── tech.ts │ │ ├── title.ts │ │ ├── torpedo.ts │ │ └── turret.ts ├── helpers │ ├── convert.ts │ ├── enums.ts │ ├── icon.ts │ ├── import+export.ts │ ├── index.ts │ ├── serializer.ts │ ├── text.ts │ ├── unique.ts │ ├── unit.ts │ └── versioning.ts ├── index.ts └── types.ts ├── tsconfig.json ├── yarn-error.log └── yarn.lock /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelind/lbn-core/4c3b0284c362d1d97386ba0c0d9471174b04d719/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | src/assets/ffg 3 | **/.DS_Store 4 | **/node_modules 5 | scripts/ffg/en 6 | scripts/ffg/de 7 | scripts/ffg/es 8 | scripts/ffg/fr 9 | *.csv 10 | *.xlsx 11 | lightning_logs/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/ 3 | tsconfig.json 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lbn-core", 3 | "version": "1.0.267", 4 | "main": "dist/index.js", 5 | "types": "dist/index.d.ts", 6 | "license": "MIT", 7 | "scripts": { 8 | "build": "rm -rf dist && yarn tsc", 9 | "prepublish": "rm -rf dist && yarn tsc", 10 | "amg": "ts-node scripts/amg/parser.ts", 11 | "amgpdf": "ts-node scripts/amg/pdfParser.ts", 12 | "ffg2xws": "node scripts/ffg2xws.js && prettier --write src/assets/ffg-xws.json", 13 | "update:xwing": "ts-node ./scripts/xwing-data/merge.ts", 14 | "update:ffg": "ts-node ./scripts/ffg/scrape.ts", 15 | "update:sirjorj": "ts-node ./scripts/sirjorj/merge.ts", 16 | "ml:train": "yarn ts-node scripts/ML/create_pilot_csv.ts; python3 scripts/ML/train_lit.py; yarn ts-node scripts/ML/update_predictions.ts; cp scripts/ML/plot_data.json ../web/public/static/plot_data.json" 17 | }, 18 | "devDependencies": { 19 | "@types/async-csv": "^2.1.1", 20 | "@types/exceljs": "^1.3.0", 21 | "@types/node": "^14.14.10", 22 | "@types/node-fetch": "^2.5.8", 23 | "@types/pdf-parse": "^1.1.1", 24 | "@types/prettier": "^2.2.0", 25 | "@types/uuid": "^8.3.0", 26 | "async-csv": "^2.1.3", 27 | "csv-writer": "^1.6.0", 28 | "exceljs": "^4.2.1", 29 | "jsonfile": "^6.1.0", 30 | "node-fetch": "^2.6.1", 31 | "ora": "^5.4.1", 32 | "pdf-parse": "^1.1.1", 33 | "pdfreader": "^2.0.0", 34 | "prettier": "^2.2.1", 35 | "ts-node": "^9.1.1", 36 | "typescript": "^4.1.2" 37 | }, 38 | "dependencies": { 39 | "redux": "^4.0.5", 40 | "uuid": "^8.3.1" 41 | }, 42 | "packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447" 43 | } 44 | -------------------------------------------------------------------------------- /scripts/ML/train_lit.py: -------------------------------------------------------------------------------- 1 | from torch.utils.tensorboard import SummaryWriter 2 | import torch 3 | import torch.nn as nn 4 | from torch.nn import functional as F 5 | 6 | from torch.utils.data import Dataset, DataLoader 7 | import torchvision 8 | import numpy as np 9 | from sklearn.model_selection import train_test_split 10 | import pytorch_lightning as pl 11 | import csv 12 | 13 | 14 | num_epochs = 1000 15 | input_size = 196 16 | h1_size = 125 17 | h2_size = 60 18 | h3_size = 20 19 | num_classes = 1 20 | batch_size = 128 21 | learning_rate = 0.0001 22 | 23 | 24 | class XWingDataset(Dataset): 25 | def __init__(self, x, y): 26 | super().__init__() 27 | self.x = torch.from_numpy(x) 28 | self.y = torch.from_numpy(y) 29 | self.n_samples = x.shape[0] 30 | 31 | def __getitem__(self, index): 32 | return self.x[index], self.y[index] 33 | 34 | def __len__(self): 35 | return self.n_samples 36 | 37 | 38 | class LitAutoEncoder(pl.LightningModule): 39 | def __init__(self): 40 | super().__init__() 41 | self.encoder = nn.Sequential( 42 | nn.Linear(input_size, h1_size), 43 | nn.ReLU(), 44 | nn.Dropout(0.25), 45 | nn.Linear(h1_size, h2_size), 46 | nn.ReLU(), 47 | nn.Dropout(0.1), 48 | nn.Linear(h2_size, h3_size), 49 | nn.ReLU(), 50 | nn.Dropout(0.1), 51 | nn.Linear(h3_size, num_classes)) 52 | self.decoder = nn.Sequential( 53 | nn.Linear(num_classes, h3_size), 54 | nn.Dropout(0.1), 55 | nn.ReLU(), 56 | nn.Linear(h3_size, h2_size), 57 | nn.Dropout(0.1), 58 | nn.ReLU(), 59 | nn.Linear(h2_size, h1_size), 60 | nn.Dropout(0.25), 61 | nn.ReLU(), 62 | nn.Linear(h1_size, input_size)) 63 | 64 | def forward(self, x): 65 | embedding = self.encoder(x) 66 | return embedding 67 | 68 | def configure_optimizers(self): 69 | optimizer = torch.optim.Adam(self.parameters(), lr=1e-3) 70 | return optimizer 71 | 72 | def training_step(self, train_batch, batch_idx): 73 | x, y = train_batch 74 | # x = x.view(x.size(0), -1) 75 | z = self.encoder(x) 76 | # x_hat = self.decoder(z) 77 | # loss = F.mse_loss(x_hat, x) 78 | loss = F.mse_loss(z, y) 79 | self.log('train_loss', loss) 80 | return loss 81 | 82 | def validation_step(self, val_batch, batch_idx): 83 | x, y = val_batch 84 | # x = x.view(x.size(0), -1) 85 | z = self.encoder(x) 86 | # x_hat = self.decoder(z) 87 | # loss = F.mse_loss(x_hat, x) 88 | loss = F.mse_loss(z, y) 89 | self.log('val_loss', loss) 90 | 91 | 92 | print("Loading CSV") 93 | raw = np.loadtxt('./scripts/ML/pilots.csv', delimiter=",", 94 | dtype=np.float32, skiprows=1) 95 | xx = raw[:, 1:] 96 | yy = raw[:, [0]] 97 | 98 | # x_train = xx[:458] 99 | # y_train = yy[:458] 100 | # x_val = xx[459:] 101 | # y_val = yy[459:] 102 | x_train = xx[:420] 103 | y_train = yy[:420] 104 | x_val = xx[421:] 105 | y_val = yy[421:] 106 | 107 | train_dataset = XWingDataset(x_train, y_train) 108 | val_dataset = XWingDataset(x_val, y_val) 109 | 110 | train_loader = DataLoader(train_dataset, batch_size=batch_size) 111 | val_loader = DataLoader(val_dataset, batch_size=batch_size) 112 | 113 | # model 114 | model = LitAutoEncoder() 115 | 116 | if __name__ == "__main__": 117 | # training 118 | trainer = pl.Trainer(max_epochs=num_epochs, accelerator="mps") 119 | trainer.fit(model, train_loader, val_loader) 120 | 121 | orig = np.loadtxt('./scripts/ML/pilots_orig.csv', delimiter=",", 122 | dtype=np.float32, skiprows=1) 123 | eval_x = torch.from_numpy(orig[:, 1:]) 124 | 125 | f = open('./scripts/ML/pilots_results.csv', 'w') 126 | writer = csv.writer(f) 127 | 128 | for i, (data) in enumerate(eval_x): 129 | data = data 130 | outputs = model(data) 131 | 132 | predicted = outputs.data[0].item() 133 | writer.writerow([round(predicted * 255)]) 134 | f.close() 135 | -------------------------------------------------------------------------------- /scripts/ML/update_predictions.ts: -------------------------------------------------------------------------------- 1 | import pilotData from '../../src/assets/pilots'; 2 | import { Faction, ShipType } from '../../src/types'; 3 | import { promises as fsPromises } from 'fs'; 4 | import * as ExcelJS from 'exceljs'; 5 | 6 | import csv from 'async-csv'; 7 | 8 | const black = '#242A2E'; 9 | const red = '#FF3069'; 10 | const green = '#4BBD5E'; 11 | const blue = '#1EAFF8'; 12 | const orange = '#FF8234'; 13 | const scum = '#cac188'; 14 | 15 | const lerpColor = (a: string, b: string, amount: number) => { 16 | var ah = parseInt(a.replace(/#/g, ''), 16), 17 | ar = ah >> 16, 18 | ag = (ah >> 8) & 0xff, 19 | ab = ah & 0xff, 20 | bh = parseInt(b.replace(/#/g, ''), 16), 21 | br = bh >> 16, 22 | bg = (bh >> 8) & 0xff, 23 | bb = bh & 0xff, 24 | rr = ar + amount * (br - ar), 25 | rg = ag + amount * (bg - ag), 26 | rb = ab + amount * (bb - ab); 27 | 28 | return ( 29 | '#' + (((1 << 24) + (rr << 16) + (rg << 8) + rb) | 0).toString(16).slice(1) 30 | ); 31 | }; 32 | 33 | export const colorForFaction = (key: Faction) => { 34 | switch (key) { 35 | case 'Rebel Alliance': 36 | return red; 37 | case 'Scum and Villainy': 38 | return scum; 39 | case 'Galactic Empire': 40 | return black; 41 | case 'Resistance': 42 | return orange; 43 | case 'First Order': 44 | return red; 45 | case 'Galactic Republic': 46 | return red; 47 | case 'Separatist Alliance': 48 | return blue; 49 | } 50 | }; 51 | 52 | const run = async () => { 53 | const csvString = await fsPromises.readFile( 54 | './scripts/ML/pilots_results.csv', 55 | 'utf-8' 56 | ); 57 | const rows = await csv.parse(csvString); 58 | 59 | const wb = new ExcelJS.Workbook(); 60 | 61 | const json: { 62 | cost: number; 63 | pred: number; 64 | diff: number; 65 | name: string; 66 | color: string; 67 | faction: Faction; 68 | ship: string; 69 | }[] = []; 70 | 71 | let i = 0; 72 | Object.keys(pilotData).map((f) => { 73 | const sh = wb.addWorksheet(f); 74 | 75 | Object.keys(pilotData[f as Faction]).map((s) => { 76 | const ship: ShipType = pilotData[f as Faction][s]; 77 | if (ship.size !== 'Huge') { 78 | // ships.push(shipType.xws); 79 | ship.pilots.forEach((pilot) => { 80 | const value = rows[i] as string[]; 81 | pilot.predictedCost = parseFloat(value[0]); 82 | 83 | const row = sh.addRow([ 84 | ship.name, 85 | pilot.name, 86 | pilot.caption, 87 | pilot.cost, 88 | pilot.predictedCost, 89 | pilot.cost - pilot.predictedCost, 90 | ]); 91 | 92 | json.push({ 93 | name: pilot.name, 94 | cost: pilot.cost, 95 | pred: pilot.predictedCost, 96 | color: colorForFaction(ship.faction), 97 | diff: pilot.cost - pilot.predictedCost, 98 | faction: ship.faction, 99 | ship: ship.name, 100 | }); 101 | 102 | const val = row.getCell(6).value! as number; 103 | const f = Math.min(Math.abs(val), 5); 104 | 105 | if (val > 0) { 106 | const color = lerpColor('#ffffff', green, f * 0.2); 107 | row.getCell(6).fill = { 108 | type: 'pattern', 109 | pattern: 'solid', 110 | fgColor: { argb: '33' + color.substr(1) }, 111 | }; 112 | } else if (val < 0) { 113 | const color = lerpColor('#ffffff', red, f * 0.2); 114 | row.getCell(6).fill = { 115 | type: 'pattern', 116 | pattern: 'solid', 117 | fgColor: { argb: '33' + color.substr(1) }, 118 | }; 119 | } 120 | 121 | i += 1; 122 | }); 123 | } 124 | }); 125 | }); 126 | 127 | await wb.xlsx.writeFile('./scripts/ML/overview.xlsx'); 128 | await fsPromises.writeFile( 129 | './scripts/ML/plot_data.json', 130 | JSON.stringify(json) 131 | ); 132 | }; 133 | 134 | run(); 135 | -------------------------------------------------------------------------------- /scripts/amg/ship_points.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelind/lbn-core/4c3b0284c362d1d97386ba0c0d9471174b04d719/scripts/amg/ship_points.pdf -------------------------------------------------------------------------------- /scripts/amg/ship_points_.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelind/lbn-core/4c3b0284c362d1d97386ba0c0d9471174b04d719/scripts/amg/ship_points_.pdf -------------------------------------------------------------------------------- /scripts/amg/upgrade_points.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelind/lbn-core/4c3b0284c362d1d97386ba0c0d9471174b04d719/scripts/amg/upgrade_points.pdf -------------------------------------------------------------------------------- /scripts/ffg/scrape.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import fetch from 'node-fetch'; 3 | import prettier from 'prettier'; 4 | import assets from '../../src/assets'; 5 | import ffgToXws from '../../src/assets/ffg-xws'; 6 | import { sourceKeys } from '../../src/helpers/enums'; 7 | import { run } from './process'; 8 | import { asyncForEach, generateXWS, getName } from './utils'; 9 | 10 | const ora = require('ora'); 11 | 12 | const baseUrl = 'https://x-wing-api.fantasyflightgames.com'; 13 | 14 | const metadataUrl = '/app-metadata'; 15 | const cardUrl = '/cards'; 16 | const expansionUrl = '/cards/extensions'; 17 | const formatsUrl = '/gameformats'; 18 | 19 | const languages = ['en-en', 'de-de', 'es-es', 'fr-fr']; 20 | 21 | const get = async (url: string, language: string) => { 22 | const result = await fetch(baseUrl + url, { 23 | headers: { 24 | 'Content-Type': 'application/json', 25 | 'Accept-Language': language, 26 | }, 27 | method: 'GET', 28 | }).then((r) => r.json()); 29 | return result; 30 | }; 31 | 32 | const fetchAndProcess = async () => { 33 | await asyncForEach(languages, async (language: string) => { 34 | // console.log(`** Fetching data for ${language} **`); 35 | const spinner = ora(`Fetching ${language}`).start(); 36 | const l = language.substring(3); 37 | 38 | if (!fs.existsSync(`./scripts/ffg/${l}`)) { 39 | fs.mkdirSync(`./scripts/ffg/${l}`); 40 | } 41 | 42 | const metadata = await get(metadataUrl, language); 43 | fs.writeFileSync( 44 | `./scripts/ffg/${l}/metadata.json`, 45 | JSON.stringify(metadata, null, 2) 46 | ); 47 | 48 | const cards = await get(cardUrl, language); 49 | fs.writeFileSync( 50 | `./scripts/ffg/${l}/cards.json`, 51 | JSON.stringify(cards, null, 2) 52 | ); 53 | 54 | const expansions: { 55 | extensions: { 56 | id: number; 57 | name: string; 58 | description: string; 59 | cover: string; 60 | url: string; 61 | card_list: { id: number; faction_id: number }[]; 62 | }[]; 63 | } = await get(expansionUrl, language); 64 | fs.writeFileSync( 65 | `./scripts/ffg/${l}/expansions.json`, 66 | JSON.stringify(expansions, null, 2) 67 | ); 68 | 69 | // Update sources 70 | for (let i = 0; i < expansions.extensions.length; i++) { 71 | const e = expansions.extensions[i]; 72 | 73 | const validCard = e.card_list.find((c) => c.faction_id !== undefined); 74 | if (!validCard) { 75 | continue; 76 | } 77 | 78 | // Get faction 79 | const faction = ffgToXws.factions[validCard.faction_id]; 80 | const source = 81 | assets.sources['Core Sets'].find((s) => s.ffg === e.id) || 82 | assets.sources['Epic'].find((s) => s.ffg === e.id) || 83 | assets.sources[faction].find((s) => s.ffg === e.id); 84 | if (!source) { 85 | const newSource = { 86 | ffg: e.id, 87 | xws: generateXWS(e.name), 88 | name: e.name, 89 | wave: -1, 90 | released: true, 91 | contents: { 92 | ships: {}, 93 | pilots: {}, 94 | upgrades: {}, 95 | }, 96 | }; 97 | assets.sources[faction].push(newSource); 98 | } 99 | } 100 | sourceKeys.forEach((key) => { 101 | const file = assets.sources[key]; 102 | 103 | const header = 104 | 'import {Source} from "../../../types";\n\nexport const t: Source[] = '; 105 | const formatted = prettier.format( 106 | `${header}${JSON.stringify(file)};\n\nexport default t;`, 107 | { 108 | trailingComma: 'all', 109 | singleQuote: true, 110 | parser: 'typescript', 111 | } 112 | ); 113 | fs.writeFileSync( 114 | `./src/assets/sources/${getName(key)}.ts`, 115 | formatted, 116 | 'utf8' 117 | ); 118 | }); 119 | 120 | const formats = await get(formatsUrl, language); 121 | const format = formats.game_formats.find((t: any) => t.game_mode === 2); 122 | if (format) { 123 | fs.writeFileSync( 124 | `./scripts/ffg/${l}/hyperspace.json`, 125 | JSON.stringify(format, null, 2) 126 | ); 127 | } 128 | spinner.succeed(); 129 | 130 | await run(l); 131 | }); 132 | }; 133 | 134 | fetchAndProcess(); 135 | -------------------------------------------------------------------------------- /scripts/ffg2xws.js: -------------------------------------------------------------------------------- 1 | // Quick script that maps ffg's `id` field to `xws` values 2 | 3 | const fs = require('fs'); 4 | const jsonfile = require('jsonfile'); 5 | 6 | const dataRoot = __dirname + '/../src/assets'; 7 | const ffg2xws = { 8 | pilots: {}, 9 | upgrades: {}, 10 | factions: {}, 11 | ships: {}, 12 | actions: {}, 13 | stats: {}, 14 | }; 15 | 16 | // Upgrades 17 | const upgradeFiles = fs.readdirSync(`${dataRoot}/upgrades`); 18 | upgradeFiles.forEach((file) => { 19 | const contents = jsonfile.readFileSync(`${dataRoot}/upgrades/${file}`); 20 | contents.forEach((upg) => { 21 | if (upg.xws) { 22 | upg.sides.forEach((side) => { 23 | if (side.ffg) { 24 | ffg2xws.upgrades[side.ffg] = upg.xws; 25 | } 26 | }); 27 | } 28 | }); 29 | }); 30 | 31 | // Pilots 32 | const factions = fs.readdirSync(`${dataRoot}/pilots`); 33 | factions.forEach((faction) => { 34 | const ships = fs.readdirSync(`${dataRoot}/pilots/${faction}`); 35 | ships.forEach((file) => { 36 | const contents = jsonfile.readFileSync( 37 | `${dataRoot}/pilots/${faction}/${file}` 38 | ); 39 | // Read the ship xws and FFG ID information 40 | if (contents.xws && contents.ffg) { 41 | ffg2xws.ships[contents.ffg] = contents.xws; 42 | } 43 | contents.pilots.forEach((pilot) => { 44 | if (pilot.xws && pilot.ffg) { 45 | ffg2xws.pilots[pilot.ffg] = pilot.xws; 46 | } 47 | }); 48 | }); 49 | }); 50 | 51 | // Factions 52 | const factionFiles = fs.readdirSync(`${dataRoot}/factions`); 53 | factionFiles.forEach((file) => { 54 | const contents = jsonfile.readFileSync(`${dataRoot}/factions/${file}`); 55 | contents.forEach((faction) => { 56 | if (faction.xws && faction.ffg) { 57 | ffg2xws.factions[faction.ffg] = faction.xws; 58 | } 59 | }); 60 | }); 61 | 62 | // Actions 63 | const actionsFiles = fs.readdirSync(`${dataRoot}/actions`); 64 | actionsFiles.forEach((file) => { 65 | const contents = jsonfile.readFileSync(`${dataRoot}/actions/${file}`); 66 | contents.forEach((action) => { 67 | if (action.xws && action.ffg) { 68 | ffg2xws.actions[action.ffg] = action.xws; 69 | } 70 | }); 71 | }); 72 | 73 | // Stats 74 | const statsFiles = fs.readdirSync(`${dataRoot}/stats`); 75 | statsFiles.forEach((file) => { 76 | const contents = jsonfile.readFileSync(`${dataRoot}/stats/${file}`); 77 | contents.forEach((stat) => { 78 | if (stat.xws && stat.ffg) { 79 | ffg2xws.stats[stat.ffg] = stat.xws; 80 | } 81 | }); 82 | }); 83 | 84 | // const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); 85 | // const ordered = Object.keys(ffg2xws) 86 | // .sort(collator.compare) 87 | // .reduce((aq, key) => { 88 | // aq[key] = ffg2xws[key]; 89 | // return aq; 90 | // }, {}); 91 | const ordered = ffg2xws; 92 | 93 | jsonfile.writeFileSync(`${dataRoot}/ffg-xws.json`, ordered); 94 | -------------------------------------------------------------------------------- /scripts/sirjorj/Common.ts: -------------------------------------------------------------------------------- 1 | export interface Action { 2 | difficulty: string; 3 | type: string; 4 | linked: Linked; 5 | } 6 | 7 | export interface Availability { 8 | name: string; 9 | sku: string; 10 | } 11 | 12 | export interface Charge { 13 | capacity: number; 14 | rechargeable: number; 15 | } 16 | 17 | export interface Force { 18 | capacity: number; 19 | rechargeable: number; 20 | } 21 | 22 | export interface Linked { 23 | difficulty: string; 24 | type: string; 25 | } 26 | -------------------------------------------------------------------------------- /scripts/sirjorj/Pilot.ts: -------------------------------------------------------------------------------- 1 | import { Action, Availability, Charge, Force } from './Common'; 2 | import { Faction, Slot } from '../../src/types'; 3 | 4 | export interface Stat { 5 | arc: string; 6 | type: string; 7 | value: number; 8 | charge: Charge; 9 | force: Force; 10 | } 11 | 12 | export interface SPilot { 13 | ability: string; 14 | actions: Action[]; 15 | availability: Availability[]; 16 | basesize: string; 17 | cardart: string; 18 | cardimg: string; 19 | cost: string; 20 | faction: Faction; 21 | ffg: string; 22 | hyperspace: string; 23 | initiative: number; 24 | limited: number; 25 | name: string; 26 | ship: string; 27 | shipAbility: string; 28 | stats: Stat[]; 29 | subtitle: string; 30 | upgrades: Slot[]; 31 | xws: string; 32 | text: string; 33 | unreleased?: boolean; 34 | keywords: string; 35 | } 36 | -------------------------------------------------------------------------------- /scripts/sirjorj/Upgrade.ts: -------------------------------------------------------------------------------- 1 | import { Action, Availability, Charge, Force } from './Common'; 2 | import { Slot } from '../../src/types'; 3 | 4 | export interface Cost { 5 | 0: number; 6 | 1: number; 7 | 2: number; 8 | 3: number; 9 | 4: number; 10 | 5: number; 11 | 6: number; 12 | variable: string; 13 | value?: number; 14 | agi0?: number; 15 | agi1?: number; 16 | agi2?: number; 17 | agi3?: number; 18 | large?: number; 19 | medium?: number; 20 | small?: number; 21 | } 22 | 23 | export interface Attack { 24 | arc: string; 25 | maxrange: number; 26 | minrange: number; 27 | ordnance: boolean; 28 | value: number; 29 | } 30 | 31 | export interface Side { 32 | ability: string; 33 | cardart: string; 34 | cardimg: string; 35 | charge: Charge; 36 | ffg: string; 37 | restrictions: string; 38 | slot: Slot[]; 39 | title: string; 40 | type: Slot; 41 | attack: Attack; 42 | actions: Action[]; 43 | text: string; 44 | force: Force; 45 | } 46 | 47 | export interface SUpgrade { 48 | availability: Availability[]; 49 | cost: Cost; 50 | hyperspace: string; 51 | limited: number; 52 | name: string; 53 | side: Side[]; 54 | xws: string; 55 | unreleased?: boolean; 56 | } 57 | -------------------------------------------------------------------------------- /scripts/xwing-data/data2-types.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Action, 3 | Faction, 4 | Size, 5 | Slot, 6 | Stat, 7 | Side as ForceSide, 8 | Arc, 9 | } from '../../src/types'; 10 | 11 | export interface XWDStat { 12 | arc: string; 13 | type: string; 14 | value: number; 15 | } 16 | 17 | export interface XWDAction { 18 | difficulty: string; 19 | type: string; 20 | } 21 | 22 | export interface XWDCharges { 23 | value: number; 24 | recovers: number; 25 | } 26 | 27 | export interface XWDShipAbility { 28 | name: string; 29 | text: string; 30 | } 31 | 32 | export interface XWDForce { 33 | value: number; 34 | recovers: number; 35 | side: ForceSide[]; 36 | } 37 | 38 | export interface XWDPilot { 39 | name: string; 40 | xws: string; 41 | caption: string; 42 | initiative: number; 43 | limited: number; 44 | cost: number; 45 | ability: string; 46 | shipAbility: XWDShipAbility; 47 | slots: Slot[]; 48 | image: string; 49 | artwork: string; 50 | ffg: number; 51 | hyperspace: boolean; 52 | keywords: string[]; 53 | force: XWDForce; 54 | conditions: string[]; 55 | text: string; 56 | } 57 | 58 | export interface XWDShip { 59 | name: string; 60 | xws: string; 61 | ffg: number; 62 | size: Size; 63 | dial: string[]; 64 | dialCodes: string[]; 65 | faction: Faction; 66 | stats: Stat[]; 67 | actions: Action[]; 68 | icon: string; 69 | pilots: XWDPilot[]; 70 | } 71 | 72 | // -------------------------- 73 | 74 | export interface XWDCharges { 75 | value: number; 76 | recovers: number; 77 | } 78 | 79 | export interface XWDAction { 80 | type: string; 81 | difficulty: string; 82 | } 83 | 84 | export interface XWDGrant { 85 | type: string; 86 | value: any; 87 | amount?: number; 88 | arc?: Arc; 89 | } 90 | 91 | export interface XWDAlt { 92 | image: string; 93 | source: string; 94 | } 95 | 96 | export interface XWDRestriction { 97 | sizes: Size[]; 98 | force_side: string[]; 99 | factions: string[]; 100 | ships: string[]; 101 | } 102 | 103 | export interface Side { 104 | title: string; 105 | type: Slot; 106 | ability: string; 107 | slots: Slot[]; 108 | charges: XWDCharges; 109 | image: string; 110 | artwork: string; 111 | ffg: number; 112 | text: string; 113 | actions: Action[]; 114 | grants: XWDGrant[]; 115 | force: XWDForce; 116 | alt: XWDAlt[]; 117 | restrictions: XWDRestriction[]; 118 | } 119 | 120 | export interface Values { 121 | 0: number; 122 | 1: number; 123 | 2: number; 124 | 3: number; 125 | 4: number; 126 | 5: number; 127 | 6: number; 128 | Small?: number; 129 | Medium?: number; 130 | Large?: number; 131 | } 132 | 133 | export interface Cost { 134 | value: number; 135 | variable: string; 136 | values: Values; 137 | } 138 | 139 | export interface XWSRestriction { 140 | sizes: string[]; 141 | action: Action; 142 | ships: string[]; 143 | factions: Faction[]; 144 | equipped: Slot[]; 145 | shipAbility: string[]; 146 | standardized?: boolean; 147 | } 148 | 149 | export interface XWDUpgrade { 150 | name: string; 151 | limited: number; 152 | xws: string; 153 | sides: Side[]; 154 | cost: Cost; 155 | restrictions: XWSRestriction[]; 156 | hyperspace: boolean; 157 | } 158 | -------------------------------------------------------------------------------- /src/assets/colors.ts: -------------------------------------------------------------------------------- 1 | export const black = "#242A2E"; 2 | 3 | export const red = "#FF3069"; 4 | export const green = "#4BBD5E"; 5 | export const yellow = "#FFD400"; 6 | export const blue = "#1EAFF8"; 7 | export const orange = "#FF8234"; 8 | export const purple = "#ce7ddb"; 9 | export const pink = "#FF54AA"; 10 | 11 | export const selection = "#e9eaec"; 12 | export const darkSelection = "#444A4E"; 13 | 14 | export const darkgrey = "#A2A3A5"; 15 | export const swipebackground = "#CBCED2"; 16 | 17 | export const buttonBlue = "#6C9AEE"; 18 | export const scum = "#cac188"; 19 | 20 | export const header = "#f2f2f4"; 21 | export const darkheader = "#444A4E"; 22 | export const menu = "#292d35"; 23 | export const search = "#959ba7"; 24 | 25 | export const dimStart = "#ffffff00"; 26 | export const dimEnd = "#ffffff80"; 27 | export const darkDimStart = "#242A2E00"; 28 | export const darkDimEnd = "#242A2E80"; 29 | 30 | export default { 31 | black, 32 | red, 33 | green, 34 | yellow, 35 | blue, 36 | orange, 37 | purple, 38 | selection, 39 | darkgrey, 40 | swipebackground, 41 | buttonBlue, 42 | scum, 43 | header, 44 | menu, 45 | search, 46 | dimStart, 47 | dimEnd, 48 | pink, 49 | }; 50 | -------------------------------------------------------------------------------- /src/assets/index.ts: -------------------------------------------------------------------------------- 1 | import pilotsImport from './pilots'; 2 | import upgradesImport from './upgrades'; 3 | import sourcesImport from './sources'; 4 | import conditionsImport from './conditions'; 5 | 6 | export const pilots = pilotsImport; 7 | export const upgrades = upgradesImport; 8 | export const sources = sourcesImport; 9 | export const conditions = conditionsImport; 10 | 11 | export default { 12 | pilots: pilotsImport, 13 | upgrades: upgradesImport, 14 | sources: sourcesImport, 15 | conditions: conditionsImport 16 | }; 17 | -------------------------------------------------------------------------------- /src/assets/pilots/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrelind/lbn-core/4c3b0284c362d1d97386ba0c0d9471174b04d719/src/assets/pilots/.DS_Store -------------------------------------------------------------------------------- /src/assets/pilots/first-order/gozanti-class-cruiser.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gozanti-class Cruiser', 5 | xws: 'gozanticlasscruiser', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FB', 14 | '2BR', 15 | '2NR', 16 | '2FB', 17 | '3FB', 18 | '4FR', 19 | ], 20 | faction: 'First Order', 21 | stats: [ 22 | { type: 'attack', arc: 'Front Arc', value: 3 }, 23 | { type: 'hull', value: 11 }, 24 | { type: 'shields', value: 5, recovers: 1 }, 25 | { type: 'energy', value: 3, recovers: 2 }, 26 | ], 27 | actions: [ 28 | { type: 'Focus', difficulty: 'White' }, 29 | { type: 'Reinforce', difficulty: 'White' }, 30 | { type: 'Lock', difficulty: 'White' }, 31 | { type: 'Coordinate', difficulty: 'White' }, 32 | { type: 'Jam', difficulty: 'White' }, 33 | ], 34 | ability: { 35 | name: 'Docking Clamps', 36 | text: 'You can dock up to 4 small ships.', 37 | }, 38 | pilots: [ 39 | { 40 | name: 'First Order Sympathizers', 41 | text: 42 | "The First Order's swift rise to power rests upon ruthless innovation. However, sympathizers often repurpose Imperial designs, like the venerable Gozanti-class cruiser, in surveillance and patrol operations.", 43 | initiative: 7, 44 | engagement: 1, 45 | limited: 0, 46 | cost: 67, 47 | xws: 'firstordersympathizers', 48 | slots: [ 49 | 'Command', 50 | 'Hardpoint', 51 | 'Crew', 52 | 'Crew', 53 | 'Gunner', 54 | 'Team', 55 | 'Cargo', 56 | 'Cargo', 57 | ], 58 | standard: false, 59 | extended: false, 60 | epic: true, 61 | ffg: 712, 62 | artwork: 63 | 'https://infinitearenas.com/xw2/images/artwork/pilots/firstordersympathizers.png', 64 | image: 65 | 'https://infinitearenas.com/xw2/images/pilots/firstordersympathizers.png', 66 | }, 67 | ], 68 | ffg: 81, 69 | icon: 70 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Gozanti.png', 71 | }; 72 | 73 | export default t; 74 | -------------------------------------------------------------------------------- /src/assets/pilots/first-order/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import gozanticlasscruiser from './gozanti-class-cruiser'; 3 | import raiderclasscorvette from './raider-class-corvette'; 4 | import tiebainterceptor from './tie-ba-interceptor'; 5 | import tiefofighter from './tie-fo-fighter'; 6 | import tiesffighter from './tie-sf-fighter'; 7 | import tievnsilencer from './tie-vn-silencer'; 8 | import upsilonclassshuttle from './upsilon-class-shuttle'; 9 | import xiclasslightshuttle from './xi-class-light-shuttle'; 10 | import tiesebomber from './tie-se-bomber'; 11 | import tiewiwhispermodifiedinterceptor from './tie-wi-whisper-modified-interceptor'; 12 | 13 | const ships: { [s: string]: ShipType } = { 14 | gozanticlasscruiser, 15 | raiderclasscorvette, 16 | tiefofighter, 17 | tiesffighter, 18 | tievnsilencer, 19 | upsilonclassshuttle, 20 | tiebainterceptor, 21 | xiclasslightshuttle, 22 | tiesebomber, 23 | tiewiwhispermodifiedinterceptor, 24 | }; 25 | 26 | export default ships; 27 | -------------------------------------------------------------------------------- /src/assets/pilots/first-order/raider-class-corvette.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Raider-class Corvette', 5 | xws: 'raiderclasscorvette', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BB', 12 | '1NB', 13 | '1FW', 14 | '2BW', 15 | '2NW', 16 | '2FB', 17 | '3BR', 18 | '3NR', 19 | '3FB', 20 | '4FW', 21 | '5FR', 22 | ], 23 | faction: 'First Order', 24 | stats: [], 25 | actions: [], 26 | ability: { 27 | name: 'Concentrated Batteries', 28 | text: 29 | 'While you perform a primary, [Torpedo] or [Missile] attack, if the defender is in your [Bullseye Arc], roll 1 additional die.', 30 | }, 31 | pilots: [ 32 | { 33 | name: 'First Order Collaborators', 34 | text: 35 | "The First Order's supporters make use of former Imperial vessels, such as the Raider-class corvette. Though it has outlived the regime that created it, this craft still spreads terror across the galaxy.", 36 | initiative: 8, 37 | engagement: 0, 38 | limited: 0, 39 | cost: 131, 40 | xws: 'firstordercollaborators', 41 | slots: [ 42 | 'Command', 43 | 'Torpedo', 44 | 'Missile', 45 | 'Hardpoint', 46 | 'Hardpoint', 47 | 'Crew', 48 | 'Crew', 49 | 'Team', 50 | 'Team', 51 | 'Cargo', 52 | ], 53 | standard: false, 54 | extended: false, 55 | epic: true, 56 | ffg: 708, 57 | artwork: 58 | 'https://infinitearenas.com/xw2/images/artwork/pilots/firstordercollaborators.png', 59 | image: 60 | 'https://infinitearenas.com/xw2/images/pilots/firstordercollaborators.png', 61 | }, 62 | ], 63 | ffg: 79, 64 | icon: 65 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Raider.png', 66 | }; 67 | 68 | export default t; 69 | -------------------------------------------------------------------------------- /src/assets/pilots/first-order/tie-ba-interceptor.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE/ba Interceptor', 5 | xws: 'tiebainterceptor', 6 | ffg: 70, 7 | size: 'Small', 8 | dial: [ 9 | '1TB', 10 | '1BB', 11 | '1NB', 12 | '1YB', 13 | '2LR', 14 | '2TW', 15 | '2BB', 16 | '2FB', 17 | '2NB', 18 | '2YW', 19 | '2PR', 20 | '3TW', 21 | '3BW', 22 | '3FB', 23 | '3NW', 24 | '3YW', 25 | '4FB', 26 | '5FW', 27 | '5KR', 28 | ], 29 | faction: 'First Order', 30 | stats: [ 31 | { arc: 'Front Arc', type: 'attack', value: 3 }, 32 | { type: 'agility', value: 3 }, 33 | { type: 'hull', value: 2 }, 34 | { type: 'shields', value: 2 }, 35 | ], 36 | actions: [ 37 | { difficulty: 'White', type: 'Focus' }, 38 | { difficulty: 'White', type: 'Evade' }, 39 | { difficulty: 'White', type: 'Lock' }, 40 | { difficulty: 'White', type: 'Barrel Roll' }, 41 | { difficulty: 'White', type: 'Boost' }, 42 | ], 43 | ability: { 44 | name: 'Fine-Tuned Thrusters', 45 | text: 46 | 'After you fully execute a maneuver, if you are not depleted or strained, you may gain 1 deplete or strain token to perform a [Lock] or [Barrel Roll] action.', 47 | }, 48 | icon: 49 | 'https://infinitearenas.com/xw2/images/shipicons/first-order/I_Vonregs-First-Order-TIE-Interceptor.png', 50 | pilots: [ 51 | { 52 | name: 'Major Vonreg', 53 | caption: 'Red Baron', 54 | initiative: 6, 55 | limited: 1, 56 | cost: 5, 57 | xws: 'majorvonreg', 58 | ability: 59 | 'During the System Phase, you may choose 1 enemy ship in your [Bullseye Arc]. That ship gains 1 deplete or strain token of your choice.', 60 | slots: [ 61 | 'Talent', 62 | 'Talent', 63 | 'Tech', 64 | 'Missile', 65 | 'Modification', 66 | 'Modification', 67 | ], 68 | standard: true, 69 | epic: true, 70 | ffg: 624, 71 | keywords: ['TIE'], 72 | loadout: 14, 73 | extended: true, 74 | image: 'https://infinitearenas.com/xw2/images/pilots/majorvonreg.png', 75 | artwork: 76 | 'https://infinitearenas.com/xw2/images/artwork/pilots/majorvonreg.png', 77 | }, 78 | { 79 | name: '“Holo”', 80 | caption: 'Trick of the Light', 81 | initiative: 5, 82 | limited: 1, 83 | cost: 5, 84 | xws: 'holo', 85 | ability: 86 | 'At the start of the Engagement Phase, you must transfer 1 of your tokens to another friendly ship at range 0-2.', 87 | slots: ['Talent', 'Tech', 'Missile', 'Modification', 'Modification'], 88 | standard: true, 89 | epic: true, 90 | ffg: 625, 91 | keywords: ['TIE'], 92 | loadout: 12, 93 | extended: true, 94 | image: 'https://infinitearenas.com/xw2/images/pilots/holo.png', 95 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/holo.png', 96 | }, 97 | { 98 | name: '“Ember”', 99 | caption: 'Dying Flame', 100 | initiative: 4, 101 | limited: 1, 102 | cost: 4, 103 | xws: 'ember', 104 | ability: 105 | 'While you perform an attack, if there is a damaged ship friendly to the defender at range 0-1 of the defender, the defender cannot spend focus or calculate tokens.', 106 | slots: ['Talent', 'Talent', 'Tech', 'Missile', 'Modification'], 107 | standard: true, 108 | epic: true, 109 | ffg: 626, 110 | keywords: ['TIE'], 111 | loadout: 7, 112 | extended: true, 113 | image: 'https://infinitearenas.com/xw2/images/pilots/ember.png', 114 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/ember.png', 115 | }, 116 | { 117 | name: 'First Order Provocateur', 118 | initiative: 3, 119 | limited: 0, 120 | cost: 4, 121 | xws: 'firstorderprovocateur', 122 | slots: ['Talent', 'Tech', 'Modification'], 123 | standard: true, 124 | epic: true, 125 | ffg: 627, 126 | text: 127 | "Major Vonreg's vision guided the enhancement of proven designs while engineering this one-of-a-kind precise and lethal craft from Sienar-Jaemus Fleet Systems.", 128 | keywords: ['TIE'], 129 | loadout: 3, 130 | extended: true, 131 | image: 132 | 'https://infinitearenas.com/xw2/images/pilots/firstorderprovocateur.png', 133 | artwork: 134 | 'https://infinitearenas.com/xw2/images/artwork/pilots/firstorderprovocateur.png', 135 | }, 136 | ], 137 | }; 138 | 139 | export default t; 140 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/alpha-class-star-wing.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Alpha-class Star Wing', 5 | xws: 'alphaclassstarwing', 6 | ffg: 14, 7 | size: 'Small', 8 | dial: [ 9 | '1BW', 10 | '1FB', 11 | '1NW', 12 | '2TW', 13 | '2BB', 14 | '2FB', 15 | '2NB', 16 | '2YW', 17 | '3TW', 18 | '3BW', 19 | '3FW', 20 | '3NW', 21 | '3YW', 22 | '4FR', 23 | ], 24 | faction: 'Galactic Empire', 25 | stats: [ 26 | { arc: 'Front Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 4 }, 29 | { type: 'shields', value: 3 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'White', type: 'Lock' }, 34 | { difficulty: 'White', type: 'SLAM' }, 35 | { difficulty: 'White', type: 'Reload' }, 36 | ], 37 | icon: 38 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_AlphaStarwing.png', 39 | pilots: [ 40 | { 41 | name: 'Lieutenant Karsabi', 42 | caption: 'Brash Noble', 43 | initiative: 3, 44 | limited: 1, 45 | cost: 5, 46 | xws: 'lieutenantkarsabi', 47 | ability: 48 | 'After you gain a disarm token, if you are not stressed, you may gain 1 stress token to remove 1 disarm token.', 49 | slots: ['Talent', 'Sensor', 'Missile', 'Modification', 'Configuration'], 50 | ffg: 136, 51 | standard: false, 52 | epic: true, 53 | loadout: 14, 54 | extended: true, 55 | image: 56 | 'https://infinitearenas.com/xw2/images/pilots/lieutenantkarsabi.png', 57 | artwork: 58 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lieutenantkarsabi.png', 59 | }, 60 | { 61 | name: 'Major Vynder', 62 | caption: 'Pragmatic Survivor', 63 | initiative: 4, 64 | limited: 1, 65 | cost: 5, 66 | xws: 'majorvynder', 67 | ability: 68 | 'While you defend, if you are disarmed, roll 1 additional defense die.', 69 | slots: ['Talent', 'Sensor', 'Torpedo', 'Modification', 'Configuration'], 70 | ffg: 135, 71 | standard: false, 72 | epic: true, 73 | loadout: 16, 74 | extended: true, 75 | image: 'https://infinitearenas.com/xw2/images/pilots/majorvynder.png', 76 | artwork: 77 | 'https://infinitearenas.com/xw2/images/artwork/pilots/majorvynder.png', 78 | }, 79 | { 80 | name: 'Nu Squadron Pilot', 81 | initiative: 2, 82 | limited: 0, 83 | cost: 5, 84 | xws: 'nusquadronpilot', 85 | text: 86 | 'With a design inspired by other Cygnus Spaceworks vessels, the Alpha-class star wing is a versatile craft assigned to Imperial Navy specialist units that need a starfighter they can outfit for multiple roles.', 87 | slots: ['Sensor', 'Cannon', 'Modification', 'Configuration'], 88 | ffg: 138, 89 | standard: false, 90 | epic: true, 91 | loadout: 7, 92 | extended: true, 93 | image: 'https://infinitearenas.com/xw2/images/pilots/nusquadronpilot.png', 94 | artwork: 95 | 'https://infinitearenas.com/xw2/images/artwork/pilots/nusquadronpilot.png', 96 | }, 97 | { 98 | name: 'Rho Squadron Pilot', 99 | initiative: 3, 100 | limited: 0, 101 | cost: 5, 102 | xws: 'rhosquadronpilot', 103 | text: 104 | 'The elite pilots of Rho Squadron instill terror in the Rebellion, using both the Xg-1 assault configuration and Os-1 arsenal loadout of the Alpha-class star wing to devastating effect.', 105 | slots: ['Talent', 'Sensor', 'Modification', 'Configuration'], 106 | ffg: 137, 107 | standard: false, 108 | epic: true, 109 | loadout: 9, 110 | extended: true, 111 | image: 112 | 'https://infinitearenas.com/xw2/images/pilots/rhosquadronpilot.png', 113 | artwork: 114 | 'https://infinitearenas.com/xw2/images/artwork/pilots/rhosquadronpilot.png', 115 | }, 116 | ], 117 | }; 118 | 119 | export default t; 120 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/gauntlet-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gauntlet Fighter', 5 | xws: 'gauntletfighter', 6 | size: 'Large', 7 | dial: [ 8 | '0OR', 9 | '1BB', 10 | '1NB', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TR', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | '3YR', 21 | '4FW', 22 | ], 23 | faction: 'Galactic Empire', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 9 }, 29 | { type: 'shields', value: 2 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Reinforce' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | ], 37 | pilots: [ 38 | { 39 | xws: 'captainhark', 40 | name: 'Captain Hark', 41 | ability: 42 | 'After you reveal a (0 [Stop]) maneuver, if you are equipped with Swivel Wings (Down), you must execute a (1 [Left Bank]) or (1 [Right Bank]) sideslip maneuver of the same difficulty instead. After you execute that maneuver, you must flip Swivel Wings (Down).', 43 | cost: 6, 44 | loadout: 14, 45 | initiative: 3, 46 | limited: 1, 47 | standard: true, 48 | extended: true, 49 | epic: true, 50 | slots: [ 51 | 'Talent', 52 | 'Crew', 53 | 'Gunner', 54 | 'Device', 55 | 'Illicit', 56 | 'Modification', 57 | 'Configuration', 58 | ], 59 | keywords: ['Mandalorian'], 60 | caption: 'Obedient Underling', 61 | image: 'https://infinitearenas.com/xw2/images/pilots/captainhark.png', 62 | artwork: 63 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainhark.png', 64 | }, 65 | { 66 | xws: 'garsaxon', 67 | name: 'Gar Saxon', 68 | ability: 69 | "While a friendly unit at range 0-2 performs a primary attack, if the attacker is in the defender's [Rear Arc], you may spend 1 [Charge]. If you do, the attacker rolls 1 additional die.", 70 | charges: { value: 2, recovers: 1 }, 71 | cost: 7, 72 | loadout: 18, 73 | initiative: 3, 74 | limited: 1, 75 | standard: true, 76 | extended: true, 77 | epic: true, 78 | slots: [ 79 | 'Talent', 80 | 'Crew', 81 | 'Gunner', 82 | 'Device', 83 | 'Illicit', 84 | 'Modification', 85 | 'Configuration', 86 | ], 87 | keywords: ['Mandalorian'], 88 | caption: 'Treacherous Viceroy', 89 | image: 'https://infinitearenas.com/xw2/images/pilots/garsaxon.png', 90 | artwork: 91 | 'https://infinitearenas.com/xw2/images/artwork/pilots/garsaxon.png', 92 | }, 93 | { 94 | xws: 'imperialsupercommando', 95 | name: 'Imperial Super Commando', 96 | cost: 7, 97 | loadout: 10, 98 | initiative: 2, 99 | limited: 0, 100 | standard: true, 101 | extended: true, 102 | epic: true, 103 | slots: [ 104 | 'Talent', 105 | 'Crew', 106 | 'Gunner', 107 | 'Device', 108 | 'Device', 109 | 'Illicit', 110 | 'Modification', 111 | 'Configuration', 112 | ], 113 | keywords: ['Mandalorian'], 114 | image: 115 | 'https://infinitearenas.com/xw2/images/pilots/imperialsupercommando.png', 116 | artwork: 117 | 'https://infinitearenas.com/xw2/images/artwork/pilots/imperialsupercommando.png', 118 | }, 119 | ], 120 | }; 121 | 122 | export default t; 123 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/gozanti-class-cruiser.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gozanti-class Cruiser', 5 | xws: 'gozanticlasscruiser', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FB', 14 | '2BR', 15 | '2NR', 16 | '2FB', 17 | '3FB', 18 | '4FR', 19 | ], 20 | faction: 'Galactic Empire', 21 | stats: [ 22 | { type: 'attack', arc: 'Front Arc', value: 3 }, 23 | { type: 'hull', value: 11 }, 24 | { type: 'shields', value: 5, recovers: 1 }, 25 | { type: 'energy', value: 3, recovers: 2 }, 26 | ], 27 | actions: [ 28 | { type: 'Focus', difficulty: 'White' }, 29 | { type: 'Reinforce', difficulty: 'White' }, 30 | { type: 'Lock', difficulty: 'White' }, 31 | { type: 'Coordinate', difficulty: 'White' }, 32 | { type: 'Jam', difficulty: 'White' }, 33 | ], 34 | ability: { 35 | name: 'Docking Clamps', 36 | text: 'You can dock up to 4 small ships.', 37 | }, 38 | pilots: [ 39 | { 40 | name: 'Outer Rim Garrison', 41 | text: 42 | 'Capable of carrying TIE fighters and operating independently for long periods of time, the Gozanti-class cruiser is a common sight in the skies of downtrodden worlds across the Outer Rim.', 43 | initiative: 7, 44 | engagement: 1, 45 | limited: 0, 46 | cost: 67, 47 | xws: 'outerrimgarrison', 48 | slots: [ 49 | 'Command', 50 | 'Hardpoint', 51 | 'Crew', 52 | 'Crew', 53 | 'Gunner', 54 | 'Team', 55 | 'Cargo', 56 | 'Cargo', 57 | 'Title', 58 | ], 59 | standard: false, 60 | extended: false, 61 | epic: true, 62 | ffg: 711, 63 | artwork: 64 | 'https://infinitearenas.com/xw2/images/artwork/pilots/outerrimgarrison.png', 65 | image: 66 | 'https://infinitearenas.com/xw2/images/pilots/outerrimgarrison.png', 67 | }, 68 | ], 69 | ffg: 81, 70 | icon: 71 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Gozanti.png', 72 | }; 73 | 74 | export default t; 75 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import alphaclassstarwing from './alpha-class-star-wing'; 3 | import gozanticlasscruiser from './gozanti-class-cruiser'; 4 | import lambdaclasst4ashuttle from './lambda-class-t-4a-shuttle'; 5 | import raiderclasscorvette from './raider-class-corvette'; 6 | import tieadvancedv1 from './tie-advanced-v1'; 7 | import tieadvancedx1 from './tie-advanced-x1'; 8 | import tieagaggressor from './tie-ag-aggressor'; 9 | import tiecapunisher from './tie-ca-punisher'; 10 | import tieddefender from './tie-d-defender'; 11 | import tieininterceptor from './tie-in-interceptor'; 12 | import tielnfighter from './tie-ln-fighter'; 13 | import tiephphantom from './tie-ph-phantom'; 14 | import tiereaper from './tie-reaper'; 15 | import tiesabomber from './tie-sa-bomber'; 16 | import tieskstriker from './tie-sk-striker'; 17 | import vt49decimator from './vt-49-decimator'; 18 | import tierbheavy from './tie-rb-heavy'; 19 | import gauntletfighter from './gauntlet-fighter'; 20 | 21 | const ships: { [s: string]: ShipType } = { 22 | alphaclassstarwing, 23 | gauntletfighter, 24 | gozanticlasscruiser, 25 | lambdaclasst4ashuttle, 26 | raiderclasscorvette, 27 | tieadvancedv1, 28 | tieadvancedx1, 29 | tieagaggressor, 30 | tiecapunisher, 31 | tieddefender, 32 | tieininterceptor, 33 | tielnfighter, 34 | tiephphantom, 35 | tiereaper, 36 | tiesabomber, 37 | tieskstriker, 38 | vt49decimator, 39 | tierbheavy, 40 | }; 41 | 42 | export default ships; 43 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/lambda-class-t-4a-shuttle.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Lambda-class T-4a Shuttle', 5 | xws: 'lambdaclasst4ashuttle', 6 | ffg: 26, 7 | size: 'Large', 8 | dial: [ 9 | '0OR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '2TR', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YR', 18 | '3BR', 19 | '3FW', 20 | '3NR', 21 | ], 22 | faction: 'Galactic Empire', 23 | stats: [ 24 | { arc: 'Front Arc', type: 'attack', value: 3 }, 25 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 26 | { type: 'agility', value: 1 }, 27 | { type: 'hull', value: 6 }, 28 | { type: 'shields', value: 4 }, 29 | ], 30 | actions: [ 31 | { difficulty: 'White', type: 'Focus' }, 32 | { difficulty: 'White', type: 'Reinforce' }, 33 | { difficulty: 'White', type: 'Coordinate' }, 34 | { difficulty: 'Red', type: 'Jam' }, 35 | ], 36 | icon: 37 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Lambda.png', 38 | pilots: [ 39 | { 40 | name: 'Captain Kagi', 41 | caption: 'The Emperor’s Shuttle Pilot', 42 | initiative: 4, 43 | limited: 1, 44 | cost: 6, 45 | xws: 'captainkagi', 46 | ability: 47 | 'At the start of the Engagement Phase, you may choose 1 or more friendly ships at range 0-3. If you do, transfer all enemy lock tokens from the chosen ships to you.', 48 | slots: ['Sensor', 'Cannon', 'Crew', 'Crew', 'Modification', 'Title'], 49 | ffg: 142, 50 | standard: false, 51 | epic: true, 52 | loadout: 22, 53 | extended: true, 54 | image: 'https://infinitearenas.com/xw2/images/pilots/captainkagi.png', 55 | artwork: 56 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainkagi.png', 57 | }, 58 | { 59 | name: 'Colonel Jendon', 60 | caption: 'Darth Vader’s Shuttle Pilot', 61 | initiative: 3, 62 | limited: 1, 63 | cost: 6, 64 | xws: 'coloneljendon', 65 | ability: 66 | 'At the start of the Activation Phase, you may spend 1 [Charge]. If you do, while friendly ships acquire locks this round, they must acquire locks beyond range 3 instead of at range 0-3.', 67 | charges: { value: 2, recovers: 0 }, 68 | slots: ['Sensor', 'Cannon', 'Cannon', 'Crew', 'Modification', 'Title'], 69 | ffg: 143, 70 | standard: false, 71 | epic: true, 72 | loadout: 20, 73 | extended: true, 74 | image: 'https://infinitearenas.com/xw2/images/pilots/coloneljendon.png', 75 | artwork: 76 | 'https://infinitearenas.com/xw2/images/artwork/pilots/coloneljendon.png', 77 | }, 78 | { 79 | name: 'Lieutenant Sai', 80 | caption: 'Death Squadron Veteran', 81 | initiative: 3, 82 | limited: 1, 83 | cost: 5, 84 | xws: 'lieutenantsai', 85 | ability: 86 | 'After you a perform a [Coordinate] action, if the ship you chose performed an action on your action bar, you may perform that action.', 87 | slots: ['Sensor', 'Cannon', 'Crew', 'Crew', 'Modification', 'Title'], 88 | ffg: 144, 89 | standard: false, 90 | epic: true, 91 | loadout: 14, 92 | extended: true, 93 | image: 'https://infinitearenas.com/xw2/images/pilots/lieutenantsai.png', 94 | artwork: 95 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lieutenantsai.png', 96 | }, 97 | { 98 | name: 'Omicron Group Pilot', 99 | initiative: 1, 100 | limited: 0, 101 | cost: 5, 102 | xws: 'omicrongrouppilot', 103 | text: 104 | 'Noted for its tri-wing design and advanced sensor suite, the Lambda-class shuttle serves a critical role as a light utility craft in the Imperial Navy.', 105 | slots: ['Sensor', 'Cannon', 'Modification'], 106 | ffg: 145, 107 | standard: false, 108 | epic: true, 109 | loadout: 8, 110 | extended: true, 111 | image: 112 | 'https://infinitearenas.com/xw2/images/pilots/omicrongrouppilot.png', 113 | artwork: 114 | 'https://infinitearenas.com/xw2/images/artwork/pilots/omicrongrouppilot.png', 115 | }, 116 | ], 117 | }; 118 | 119 | export default t; 120 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/raider-class-corvette.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Raider-class Corvette', 5 | xws: 'raiderclasscorvette', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BB', 12 | '1NB', 13 | '1FW', 14 | '2BW', 15 | '2NW', 16 | '2FB', 17 | '3BR', 18 | '3NR', 19 | '3FB', 20 | '4FW', 21 | '5FR', 22 | ], 23 | faction: 'Galactic Empire', 24 | stats: [], 25 | actions: [], 26 | ability: { 27 | name: 'Concentrated Batteries', 28 | text: 29 | 'While you perform a primary, [Torpedo] or [Missile] attack, if the defender is in your [Bullseye Arc], roll 1 additional die.', 30 | }, 31 | pilots: [ 32 | { 33 | name: 'Outer Rim Patrol', 34 | text: 35 | "The Raider-class corvette is one of the Empire's smallest warships, often used for reconnaissance missions, surgical strikes, or suppressing enemy starfighters with its powerful ordnance.", 36 | initiative: 8, 37 | engagement: 0, 38 | limited: 0, 39 | cost: 134, 40 | xws: 'outerrimpatrol', 41 | slots: [ 42 | 'Command', 43 | 'Torpedo', 44 | 'Missile', 45 | 'Hardpoint', 46 | 'Hardpoint', 47 | 'Crew', 48 | 'Crew', 49 | 'Team', 50 | 'Team', 51 | 'Cargo', 52 | 'Title', 53 | ], 54 | standard: false, 55 | extended: false, 56 | epic: true, 57 | ffg: 707, 58 | artwork: 59 | 'https://infinitearenas.com/xw2/images/artwork/pilots/outerrimpatrol.png', 60 | image: 'https://infinitearenas.com/xw2/images/pilots/outerrimpatrol.png', 61 | }, 62 | ], 63 | ffg: 79, 64 | icon: 65 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Raider.png', 66 | }; 67 | 68 | export default t; 69 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/tie-ag-aggressor.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE/ag Aggressor', 5 | xws: 'tieagaggressor', 6 | ffg: 29, 7 | size: 'Small', 8 | dial: [ 9 | '1BW', 10 | '1FB', 11 | '1NW', 12 | '2TW', 13 | '2BB', 14 | '2FB', 15 | '2NB', 16 | '2YW', 17 | '3TW', 18 | '3BW', 19 | '3FB', 20 | '3NW', 21 | '3YW', 22 | '4FW', 23 | '4KR', 24 | ], 25 | faction: 'Galactic Empire', 26 | stats: [ 27 | { arc: 'Front Arc', type: 'attack', value: 2 }, 28 | { type: 'agility', value: 2 }, 29 | { type: 'hull', value: 4 }, 30 | { type: 'shields', value: 1 }, 31 | ], 32 | actions: [ 33 | { difficulty: 'White', type: 'Focus' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { 36 | difficulty: 'White', 37 | linked: { difficulty: 'Red', type: 'Evade' }, 38 | type: 'Barrel Roll', 39 | }, 40 | ], 41 | icon: 42 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_TIEAggressor.png', 43 | pilots: [ 44 | { 45 | name: '“Double Edge”', 46 | caption: 'Contingency Planner', 47 | initiative: 2, 48 | limited: 1, 49 | cost: 4, 50 | xws: 'doubleedge', 51 | ability: 52 | 'After you perform a [Turret] or [Missile] attack that misses, you may perform a bonus attack using a different weapon.', 53 | slots: [ 54 | 'Talent', 55 | 'Turret', 56 | 'Missile', 57 | 'Missile', 58 | 'Gunner', 59 | 'Modification', 60 | ], 61 | ffg: 128, 62 | standard: false, 63 | epic: true, 64 | keywords: ['TIE'], 65 | loadout: 13, 66 | extended: true, 67 | image: 'https://infinitearenas.com/xw2/images/pilots/doubleedge.png', 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/doubleedge.png', 70 | }, 71 | { 72 | name: 'Lieutenant Kestal', 73 | caption: 'Innate Deadeye', 74 | initiative: 4, 75 | limited: 1, 76 | cost: 5, 77 | xws: 'lieutenantkestal', 78 | ability: 79 | "While you perform an attack, after the defender rolls defense dice, you may spend 1 focus token to cancel all of the defender's blank/[Focus] results.", 80 | slots: [ 81 | 'Talent', 82 | 'Turret', 83 | 'Missile', 84 | 'Missile', 85 | 'Gunner', 86 | 'Modification', 87 | 'Modification', 88 | ], 89 | ffg: 127, 90 | standard: false, 91 | epic: true, 92 | keywords: ['TIE'], 93 | loadout: 19, 94 | extended: true, 95 | image: 96 | 'https://infinitearenas.com/xw2/images/pilots/lieutenantkestal.png', 97 | artwork: 98 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lieutenantkestal.png', 99 | }, 100 | { 101 | name: 'Onyx Squadron Scout', 102 | initiative: 3, 103 | limited: 0, 104 | cost: 4, 105 | xws: 'onyxsquadronscout', 106 | text: 107 | 'Designed for extended engagements, the TIE/ag is flown primarily by elite pilots trained to leverage both its unique weapons loadout and its maneuverability to full effect.', 108 | slots: ['Talent', 'Turret', 'Missile', 'Gunner'], 109 | ffg: 129, 110 | standard: false, 111 | epic: true, 112 | keywords: ['TIE'], 113 | loadout: 12, 114 | extended: true, 115 | image: 116 | 'https://infinitearenas.com/xw2/images/pilots/onyxsquadronscout.png', 117 | artwork: 118 | 'https://infinitearenas.com/xw2/images/artwork/pilots/onyxsquadronscout.png', 119 | }, 120 | { 121 | name: 'Sienar Specialist', 122 | initiative: 2, 123 | limited: 0, 124 | cost: 4, 125 | xws: 'sienarspecialist', 126 | text: 127 | 'During the development of the TIE aggressor, Sienar Fleet Systems valued performance and versatility over raw cost efficiency.', 128 | slots: ['Turret', 'Missile', 'Gunner', 'Modification'], 129 | ffg: 130, 130 | standard: false, 131 | epic: true, 132 | keywords: ['TIE'], 133 | loadout: 8, 134 | extended: true, 135 | image: 136 | 'https://infinitearenas.com/xw2/images/pilots/sienarspecialist.png', 137 | artwork: 138 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sienarspecialist.png', 139 | }, 140 | ], 141 | }; 142 | 143 | export default t; 144 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/tie-ca-punisher.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE/ca Punisher', 5 | xws: 'tiecapunisher', 6 | ffg: 20, 7 | size: 'Medium', 8 | dial: [ 9 | '0OR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '2TW', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YW', 18 | '3TR', 19 | '3BW', 20 | '3FW', 21 | '3NW', 22 | '3YR', 23 | '4KR', 24 | ], 25 | faction: 'Galactic Empire', 26 | stats: [ 27 | { arc: 'Front Arc', type: 'attack', value: 2 }, 28 | { type: 'agility', value: 1 }, 29 | { type: 'hull', value: 6 }, 30 | { type: 'shields', value: 3 }, 31 | ], 32 | actions: [ 33 | { difficulty: 'White', type: 'Focus' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Barrel Roll' }, 36 | { 37 | difficulty: 'White', 38 | linked: { difficulty: 'Red', type: 'Lock' }, 39 | type: 'Boost', 40 | }, 41 | { difficulty: 'White', type: 'Reload' }, 42 | ], 43 | icon: 44 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_TIEPunisher.png', 45 | pilots: [ 46 | { 47 | name: '“Deathrain”', 48 | caption: 'Dexterous Bombardier', 49 | initiative: 4, 50 | limited: 1, 51 | cost: 6, 52 | xws: 'deathrain', 53 | ability: 'After you drop or launch a device, you may perform an action.', 54 | slots: [ 55 | 'Talent', 56 | 'Sensor', 57 | 'Torpedo', 58 | 'Missile', 59 | 'Gunner', 60 | 'Device', 61 | 'Device', 62 | 'Modification', 63 | ], 64 | ffg: 140, 65 | standard: false, 66 | epic: true, 67 | keywords: ['TIE'], 68 | loadout: 20, 69 | extended: true, 70 | image: 'https://infinitearenas.com/xw2/images/pilots/deathrain.png', 71 | artwork: 72 | 'https://infinitearenas.com/xw2/images/artwork/pilots/deathrain.png', 73 | }, 74 | { 75 | name: '“Redline”', 76 | caption: 'Adrenaline Junkie', 77 | initiative: 5, 78 | limited: 1, 79 | cost: 7, 80 | xws: 'redline', 81 | ability: 82 | 'You can maintain up to 2 locks. After you perform an action, you may acquire a lock.', 83 | slots: [ 84 | 'Sensor', 85 | 'Torpedo', 86 | 'Missile', 87 | 'Missile', 88 | 'Gunner', 89 | 'Device', 90 | 'Modification', 91 | 'Modification', 92 | ], 93 | ffg: 139, 94 | standard: false, 95 | epic: true, 96 | keywords: ['TIE'], 97 | loadout: 25, 98 | extended: true, 99 | image: 'https://infinitearenas.com/xw2/images/pilots/redline.png', 100 | artwork: 101 | 'https://infinitearenas.com/xw2/images/artwork/pilots/redline.png', 102 | }, 103 | { 104 | name: 'Cutlass Squadron Pilot', 105 | initiative: 2, 106 | limited: 0, 107 | cost: 5, 108 | xws: 'cutlasssquadronpilot', 109 | text: 110 | "The TIE punisher's design builds upon the success of the TIE bomber, adding shielding, a second bomb chute, and three additional ordnance pods, each equipped with a twin ion engine.", 111 | slots: [ 112 | 'Sensor', 113 | 'Torpedo', 114 | 'Missile', 115 | 'Gunner', 116 | 'Device', 117 | 'Modification', 118 | ], 119 | ffg: 141, 120 | standard: false, 121 | epic: true, 122 | keywords: ['TIE'], 123 | loadout: 6, 124 | extended: true, 125 | image: 126 | 'https://infinitearenas.com/xw2/images/pilots/cutlasssquadronpilot.png', 127 | artwork: 128 | 'https://infinitearenas.com/xw2/images/artwork/pilots/cutlasssquadronpilot.png', 129 | }, 130 | ], 131 | }; 132 | 133 | export default t; 134 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/tie-ph-phantom.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE/ph Phantom', 5 | xws: 'tiephphantom', 6 | ffg: 27, 7 | size: 'Small', 8 | dial: [ 9 | '1TW', 10 | '1BW', 11 | '1NW', 12 | '1YW', 13 | '2TW', 14 | '2BB', 15 | '2FB', 16 | '2NB', 17 | '2YW', 18 | '3TW', 19 | '3BW', 20 | '3FB', 21 | '3NW', 22 | '3YW', 23 | '3KR', 24 | '4FW', 25 | '4KR', 26 | ], 27 | faction: 'Galactic Empire', 28 | stats: [ 29 | { arc: 'Front Arc', type: 'attack', value: 3 }, 30 | { type: 'agility', value: 2 }, 31 | { type: 'hull', value: 3 }, 32 | { type: 'shields', value: 2 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'White', type: 'Evade' }, 37 | { difficulty: 'White', type: 'Barrel Roll' }, 38 | { difficulty: 'White', type: 'Cloak' }, 39 | ], 40 | ability: { 41 | name: 'Stygium Array', 42 | text: 43 | 'After you decloak, you may perform an [Evade] action. At the start of the End Phase, you may spend 1 evade token to gain 1 cloak token.', 44 | }, 45 | icon: 46 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_TIEPhantom.png', 47 | pilots: [ 48 | { 49 | name: '“Echo”', 50 | caption: 'Slippery Trickster', 51 | initiative: 4, 52 | limited: 1, 53 | cost: 5, 54 | xws: 'echo', 55 | ability: 56 | 'While you decloak, you must use the (2 [Bank Left]) or (2 [Bank Right]) template instead of the (2 [Straight]) template.', 57 | slots: ['Talent', 'Talent', 'Sensor', 'Gunner', 'Modification'], 58 | ffg: 132, 59 | standard: false, 60 | epic: true, 61 | keywords: ['TIE'], 62 | loadout: 9, 63 | extended: true, 64 | image: 'https://infinitearenas.com/xw2/images/pilots/echo.png', 65 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/echo.png', 66 | }, 67 | { 68 | name: '“Whisper”', 69 | caption: 'Soft-Spoken Slayer', 70 | initiative: 5, 71 | limited: 1, 72 | cost: 5, 73 | xws: 'whisper', 74 | ability: 'After you perform an attack that hits, gain 1 evade token.', 75 | slots: ['Talent', 'Sensor', 'Gunner', 'Modification', 'Modification'], 76 | ffg: 131, 77 | standard: false, 78 | epic: true, 79 | keywords: ['TIE'], 80 | loadout: 8, 81 | extended: true, 82 | image: 'https://infinitearenas.com/xw2/images/pilots/whisper.png', 83 | artwork: 84 | 'https://infinitearenas.com/xw2/images/artwork/pilots/whisper.png', 85 | }, 86 | { 87 | name: 'Imdaar Test Pilot', 88 | initiative: 3, 89 | limited: 0, 90 | cost: 5, 91 | xws: 'imdaartestpilot', 92 | text: 93 | 'The primary result of a hidden research facility on Imdaar Alpha, the TIE phantom achieves what many thought was impossible: a small starfighter equipped with an advanced cloaking device.', 94 | slots: ['Sensor', 'Gunner', 'Modification'], 95 | ffg: 134, 96 | standard: false, 97 | epic: true, 98 | keywords: ['TIE'], 99 | loadout: 6, 100 | extended: true, 101 | image: 'https://infinitearenas.com/xw2/images/pilots/imdaartestpilot.png', 102 | artwork: 103 | 'https://infinitearenas.com/xw2/images/artwork/pilots/imdaartestpilot.png', 104 | }, 105 | { 106 | name: 'Sigma Squadron Ace', 107 | initiative: 4, 108 | limited: 0, 109 | cost: 6, 110 | xws: 'sigmasquadronace', 111 | text: 112 | 'Featuring a hyperdrive and shields, the TIE phantom is also equipped with five laser cannons, giving it substantial firepower for an Imperial fighter.', 113 | slots: ['Talent', 'Sensor', 'Gunner', 'Modification'], 114 | ffg: 133, 115 | standard: false, 116 | epic: true, 117 | keywords: ['TIE'], 118 | loadout: 9, 119 | extended: true, 120 | image: 121 | 'https://infinitearenas.com/xw2/images/pilots/sigmasquadronace.png', 122 | artwork: 123 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sigmasquadronace.png', 124 | }, 125 | ], 126 | }; 127 | 128 | export default t; 129 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/tie-reaper.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE Reaper', 5 | xws: 'tiereaper', 6 | ffg: 43, 7 | size: 'Medium', 8 | dial: [ 9 | '0OR', 10 | '1LR', 11 | '1TR', 12 | '1BB', 13 | '1FB', 14 | '1NB', 15 | '1YR', 16 | '1PR', 17 | '2TR', 18 | '2BW', 19 | '2FB', 20 | '2NW', 21 | '2YR', 22 | '3BW', 23 | '3FB', 24 | '3NW', 25 | ], 26 | faction: 'Galactic Empire', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 3 }, 29 | { type: 'agility', value: 1 }, 30 | { type: 'hull', value: 6 }, 31 | { type: 'shields', value: 2 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Evade' }, 36 | { difficulty: 'Red', type: 'Coordinate' }, 37 | { difficulty: 'White', type: 'Jam' }, 38 | ], 39 | ability: { 40 | name: 'Controlled Ailerons', 41 | text: 42 | 'Before you reveal your dial, if you are not stressed, you may boost.', 43 | }, 44 | icon: 45 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_TIEReaper.png', 46 | pilots: [ 47 | { 48 | name: '“Vizier”', 49 | caption: 'Ruthless Tactician', 50 | initiative: 2, 51 | limited: 1, 52 | cost: 4, 53 | xws: 'vizier', 54 | ability: 55 | 'After you fully execute a speed 1 maneuver using your Adaptive Ailerons ship ability, you may perform a [Coordinate] action. If you do, skip your Perform Action step.', 56 | slots: ['Crew', 'Crew', 'Modification'], 57 | ffg: 115, 58 | standard: true, 59 | epic: true, 60 | keywords: ['TIE'], 61 | loadout: 12, 62 | extended: true, 63 | image: 'https://infinitearenas.com/xw2/images/pilots/vizier.png', 64 | artwork: 65 | 'https://infinitearenas.com/xw2/images/artwork/pilots/vizier.png', 66 | }, 67 | { 68 | name: 'Captain Feroph', 69 | caption: 'Imperial Courier', 70 | initiative: 3, 71 | limited: 1, 72 | cost: 4, 73 | xws: 'captainferoph', 74 | ability: 75 | 'While you defend, if the attacker does not have any green tokens, you may change 1 of your blank or [Focus] results to an [Evade] result.', 76 | slots: ['Talent', 'Crew', 'Modification', 'Modification'], 77 | ffg: 114, 78 | standard: true, 79 | epic: true, 80 | keywords: ['TIE'], 81 | loadout: 5, 82 | extended: true, 83 | image: 'https://infinitearenas.com/xw2/images/pilots/captainferoph.png', 84 | artwork: 85 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainferoph.png', 86 | }, 87 | { 88 | name: 'Major Vermeil', 89 | caption: 'Veteran of Scarif', 90 | initiative: 4, 91 | limited: 1, 92 | cost: 5, 93 | xws: 'majorvermeil', 94 | ability: 95 | 'While you perform an attack, if the defender does not have any green tokens, you may change 1 of your blank or [Focus] results to a [Hit] result.', 96 | slots: ['Talent', 'Crew', 'Crew', 'Modification'], 97 | ffg: 113, 98 | standard: true, 99 | epic: true, 100 | keywords: ['TIE'], 101 | loadout: 16, 102 | extended: true, 103 | image: 'https://infinitearenas.com/xw2/images/pilots/majorvermeil.png', 104 | artwork: 105 | 'https://infinitearenas.com/xw2/images/artwork/pilots/majorvermeil.png', 106 | }, 107 | { 108 | name: 'Scarif Base Pilot', 109 | initiative: 1, 110 | limited: 0, 111 | cost: 4, 112 | xws: 'scarifbasepilot', 113 | text: 114 | "The TIE reaper was designed to ferry elite troops to flashpoints on the battlefield, notably carrying Director Krennic's dreaded death troopers at the Battle of Scarif.", 115 | slots: ['Crew', 'Modification'], 116 | ffg: 116, 117 | standard: true, 118 | epic: true, 119 | keywords: ['TIE'], 120 | loadout: 6, 121 | extended: true, 122 | image: 'https://infinitearenas.com/xw2/images/pilots/scarifbasepilot.png', 123 | artwork: 124 | 'https://infinitearenas.com/xw2/images/artwork/pilots/scarifbasepilot.png', 125 | }, 126 | ], 127 | }; 128 | 129 | export default t; 130 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-empire/vt-49-decimator.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'VT-49 Decimator', 5 | xws: 'vt49decimator', 6 | ffg: 28, 7 | size: 'Large', 8 | dial: [ 9 | '1TR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '1YR', 14 | '2TW', 15 | '2BW', 16 | '2FB', 17 | '2NW', 18 | '2YW', 19 | '3TW', 20 | '3BW', 21 | '3FW', 22 | '3NW', 23 | '3YW', 24 | '4FW', 25 | ], 26 | faction: 'Galactic Empire', 27 | stats: [ 28 | { arc: 'Double Turret Arc', type: 'attack', value: 3 }, 29 | { type: 'agility', value: 0 }, 30 | { type: 'hull', value: 12 }, 31 | { type: 'shields', value: 4 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { difficulty: 'White', type: 'Reinforce' }, 37 | { difficulty: 'White', type: 'Rotate Arc' }, 38 | { difficulty: 'Red', type: 'Coordinate' }, 39 | ], 40 | icon: 41 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-empire/I_Decimator.png', 42 | pilots: [ 43 | { 44 | name: 'Captain Oicunn', 45 | caption: 'Inspired Tactician', 46 | initiative: 3, 47 | limited: 1, 48 | cost: 7, 49 | xws: 'captainoicunn', 50 | ability: 51 | 'While you perform an attack at attack range 0, treat it as an attack at attack range 1.', 52 | slots: [ 53 | 'Talent', 54 | 'Talent', 55 | 'Torpedo', 56 | 'Crew', 57 | 'Crew', 58 | 'Gunner', 59 | 'Device', 60 | 'Modification', 61 | 'Title', 62 | ], 63 | ffg: 146, 64 | standard: true, 65 | epic: true, 66 | loadout: 19, 67 | extended: true, 68 | image: 'https://infinitearenas.com/xw2/images/pilots/captainoicunn.png', 69 | artwork: 70 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainoicunn.png', 71 | }, 72 | { 73 | name: 'Patrol Leader', 74 | initiative: 2, 75 | limited: 0, 76 | cost: 7, 77 | xws: 'patrolleader', 78 | text: 79 | 'To be granted command of a VT-49 Decimator is seen as a significant promotion for a middling officer of the Imperial Navy.', 80 | slots: ['Torpedo', 'Crew', 'Gunner', 'Device', 'Modification'], 81 | ffg: 148, 82 | standard: true, 83 | epic: true, 84 | loadout: 12, 85 | extended: true, 86 | image: 'https://infinitearenas.com/xw2/images/pilots/patrolleader.png', 87 | artwork: 88 | 'https://infinitearenas.com/xw2/images/artwork/pilots/patrolleader.png', 89 | }, 90 | { 91 | name: 'Rear Admiral Chiraneau', 92 | caption: 'Advisor to Admiral Piett', 93 | initiative: 5, 94 | limited: 1, 95 | cost: 7, 96 | xws: 'rearadmiralchiraneau', 97 | ability: 98 | 'While you perform an attack, if you are reinforced and the defender is in the [Full Front Arc] or [Full Rear Arc] matching your reinforce token, you may change 1 of your [Focus] results to a [Critical Hit] result.', 99 | slots: [ 100 | 'Talent', 101 | 'Torpedo', 102 | 'Crew', 103 | 'Crew', 104 | 'Crew', 105 | 'Gunner', 106 | 'Device', 107 | 'Modification', 108 | 'Title', 109 | ], 110 | ffg: 147, 111 | standard: true, 112 | epic: true, 113 | loadout: 20, 114 | extended: true, 115 | image: 116 | 'https://infinitearenas.com/xw2/images/pilots/rearadmiralchiraneau.png', 117 | artwork: 118 | 'https://infinitearenas.com/xw2/images/artwork/pilots/rearadmiralchiraneau.png', 119 | }, 120 | { 121 | name: 'Morna Kee', 122 | caption: 'Determined Attaché', 123 | initiative: 4, 124 | limited: 1, 125 | cost: 7, 126 | xws: 'mornakee', 127 | ability: 128 | 'During the End Phase, you may spend 1 [Charge] to flip 1 of your reinforce tokens to your other full arc instead of removing it.', 129 | charges: { value: 3, recovers: 0 }, 130 | slots: [ 131 | 'Talent', 132 | 'Torpedo', 133 | 'Crew', 134 | 'Crew', 135 | 'Gunner', 136 | 'Device', 137 | 'Modification', 138 | 'Modification', 139 | 'Title', 140 | ], 141 | standard: true, 142 | epic: true, 143 | ffg: 634, 144 | loadout: 22, 145 | extended: true, 146 | image: 'https://infinitearenas.com/xw2/images/pilots/mornakee.png', 147 | artwork: 148 | 'https://infinitearenas.com/xw2/images/artwork/pilots/mornakee.png', 149 | }, 150 | ], 151 | }; 152 | 153 | export default t; 154 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-republic/cr90-corellian-corvette.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'CR90 Corellian Corvette', 5 | xws: 'cr90corelliancorvette', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FW', 14 | '2BB', 15 | '2NB', 16 | '2FB', 17 | '3NR', 18 | '3FB', 19 | '3BR', 20 | '4FR', 21 | '5FR', 22 | ], 23 | faction: 'Galactic Republic', 24 | stats: [ 25 | { type: 'attack', arc: 'Left Arc', value: 4 }, 26 | { type: 'attack', arc: 'Right Arc', value: 4 }, 27 | { type: 'hull', value: 18 }, 28 | { type: 'shields', value: 7, recovers: 2 }, 29 | { type: 'energy', value: 7, recovers: 2 }, 30 | ], 31 | actions: [ 32 | { type: 'Focus', difficulty: 'White' }, 33 | { type: 'Reinforce', difficulty: 'White' }, 34 | { type: 'Lock', difficulty: 'White' }, 35 | { type: 'Coordinate', difficulty: 'Red' }, 36 | { type: 'Jam', difficulty: 'Red' }, 37 | ], 38 | ability: { 39 | name: 'Broadside Batteries', 40 | text: 'You can acquire locks and perform primary attacks at range 1-4.', 41 | }, 42 | pilots: [ 43 | { 44 | name: 'Republic Judiciary', 45 | text: 46 | 'The Galactic Republic uses small, swift warships such as the CR90 corvette to respond rapidly to Separatist incursions across the galaxy.', 47 | initiative: 8, 48 | engagement: 0, 49 | limited: 0, 50 | cost: 131, 51 | xws: 'republicjudiciary', 52 | slots: [ 53 | 'Command', 54 | 'Hardpoint', 55 | 'Hardpoint', 56 | 'Crew', 57 | 'Crew', 58 | 'Gunner', 59 | 'Team', 60 | 'Team', 61 | 'Cargo', 62 | ], 63 | standard: false, 64 | extended: false, 65 | epic: true, 66 | ffg: 705, 67 | artwork: 68 | 'https://infinitearenas.com/xw2/images/artwork/pilots/republicjudiciary.png', 69 | image: 70 | 'https://infinitearenas.com/xw2/images/pilots/republicjudiciary.png', 71 | }, 72 | ], 73 | ffg: 78, 74 | icon: 75 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-republic/I_CR90.png', 76 | }; 77 | 78 | export default t; 79 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-republic/gauntlet-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gauntlet Fighter', 5 | xws: 'gauntletfighter', 6 | size: 'Large', 7 | dial: [ 8 | '0OR', 9 | '1BB', 10 | '1NB', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TR', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | '3YR', 21 | '4FW', 22 | ], 23 | faction: 'Galactic Republic', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 9 }, 29 | { type: 'shields', value: 2 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Reinforce' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | ], 37 | pilots: [ 38 | { 39 | xws: 'bokatankryze', 40 | name: 'Bo-Katan Kryze', 41 | caption: 'Nite Owl Commander', 42 | ability: 43 | 'After you fully execute a maneuver, you may gain 1 deplete token to choose an object in your [Front Arc] at range 1-2. If you do, another friendly ship may perform a [Lock] action to lock that object.', 44 | cost: 6, 45 | loadout: 12, 46 | initiative: 4, 47 | limited: 1, 48 | standard: true, 49 | extended: true, 50 | epic: true, 51 | slots: [ 52 | 'Talent', 53 | 'Crew', 54 | 'Torpedo', 55 | 'Gunner', 56 | 'Device', 57 | 'Illicit', 58 | 'Modification', 59 | 'Modification', 60 | 'Configuration', 61 | 'Title', 62 | ], 63 | keywords: ['Mandalorian'], 64 | image: 65 | 'https://infinitearenas.com/xw2/images/pilots/bokatankryze-galactic-republic.png', 66 | artwork: 67 | 'https://infinitearenas.com/xw2/images/artwork/pilots/bokatankryze-galactic-republic.png', 68 | }, 69 | { 70 | xws: 'niteowlliberator', 71 | name: 'Nite Owl Liberator', 72 | cost: 7, 73 | loadout: 12, 74 | initiative: 2, 75 | limited: 1, 76 | standard: true, 77 | extended: true, 78 | epic: true, 79 | slots: [ 80 | 'Talent', 81 | 'Crew', 82 | 'Gunner', 83 | 'Device', 84 | 'Modification', 85 | 'Configuration', 86 | ], 87 | keywords: ['Mandalorian'], 88 | caption: 'Resolute Warrior', 89 | image: 90 | 'https://infinitearenas.com/xw2/images/pilots/niteowlliberator.png', 91 | artwork: 92 | 'https://infinitearenas.com/xw2/images/artwork/pilots/niteowlliberator.png', 93 | }, 94 | ], 95 | }; 96 | 97 | export default t; 98 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-republic/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import arc170starfighter from './arc-170-starfighter'; 3 | import btlbywing from './btl-b-y-wing'; 4 | import cr90corelliancorvette from './cr90-corellian-corvette'; 5 | import delta7aethersprite from './delta-7-aethersprite'; 6 | import delta7baethersprite from './delta-7b-aethersprite'; 7 | import eta2actis from './eta-2-actis'; 8 | import laatigunship from './laat-i-gunship'; 9 | import nabooroyaln1starfighter from './naboo-royal-n-1-starfighter'; 10 | import nimbusclassvwing from './nimbus-class-v-wing'; 11 | import syliureclasshyperspacering from './syliure-class-hyperspace-ring'; 12 | import v19torrentstarfighter from './v-19-torrent-starfighter'; 13 | import gauntletfighter from './gauntlet-fighter'; 14 | import clonez95headhunter from './clone-z-95-headhunter' 15 | 16 | const ships: { [s: string]: ShipType } = { 17 | arc170starfighter, 18 | btlbywing, 19 | cr90corelliancorvette, 20 | delta7aethersprite, 21 | delta7baethersprite, 22 | gauntletfighter, 23 | nabooroyaln1starfighter, 24 | v19torrentstarfighter, 25 | eta2actis, 26 | laatigunship, 27 | nimbusclassvwing, 28 | syliureclasshyperspacering, 29 | clonez95headhunter 30 | }; 31 | 32 | export default ships; 33 | -------------------------------------------------------------------------------- /src/assets/pilots/galactic-republic/syliure-class-hyperspace-ring.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Syliure-class Hyperspace Ring', 5 | xws: 'syliureclasshyperspacering', 6 | size: 'Small', 7 | dial: [], 8 | faction: 'Galactic Republic', 9 | stats: [ 10 | { type: 'agility', value: 1 }, 11 | { type: 'hull', value: 1 }, 12 | { type: 'shields', value: 2 }, 13 | ], 14 | actions: [], 15 | ability: { 16 | name: 'Hyperspace Docking Ring', 17 | text: 18 | "1 Delta-7 Aethersprite, Eta-2 Actis, or Nimbus-class V-wing can dock with you.\n\nWhile a ship is docked with you, you gain that ship's initiative and are assigned that ship's dial. While you execute a maneuver, reduce its speed to 1. Before you execute an advanced maneuver, execute a white stationary maneuver ([Stop]) instead, then you may rotate 90º or 180º.\n\nWhile no ship is docked with you, you are not assigned a maneuver dial and do not activate or engage.", 19 | }, 20 | pilots: [ 21 | { 22 | xws: 'transgalmegcontrollink', 23 | name: 'TransGalMeg Control Link', 24 | cost: 2, 25 | initiative: 0, 26 | limited: 0, 27 | slots: ['Hyperdrive'], 28 | standard: false, 29 | epic: true, 30 | ffg: 787, 31 | loadout: 0, 32 | extended: false, 33 | image: 34 | 'https://infinitearenas.com/xw2/images/pilots/transgalmegcontrollink.png', 35 | artwork: 36 | 'https://infinitearenas.com/xw2/images/artwork/pilots/transgalmegcontrollink.png', 37 | }, 38 | ], 39 | icon: 40 | 'https://infinitearenas.com/xw2/images/shipicons/galactic-republic/I_Syliure-class_Hyperspace_Ring.png', 41 | }; 42 | 43 | export default t; 44 | -------------------------------------------------------------------------------- /src/assets/pilots/index.ts: -------------------------------------------------------------------------------- 1 | import firstOrder from './first-order'; 2 | import galacticEmpire from './galactic-empire'; 3 | import galacticRepublic from './galactic-republic'; 4 | import rebelAlliance from './rebel-alliance'; 5 | import resistance from './resistance'; 6 | import scumAndVillainy from './scum-and-villainy'; 7 | import separatistAlliance from './separatist-alliance'; 8 | 9 | export default { 10 | 'First Order': firstOrder, 11 | 'Galactic Empire': galacticEmpire, 12 | 'Galactic Republic': galacticRepublic, 13 | 'Rebel Alliance': rebelAlliance, 14 | Resistance: resistance, 15 | 'Scum and Villainy': scumAndVillainy, 16 | 'Separatist Alliance': separatistAlliance 17 | }; 18 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/arc-170-starfighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'ARC-170 Starfighter', 5 | xws: 'arc170starfighter', 6 | ffg: 31, 7 | size: 'Medium', 8 | dial: [ 9 | '1BB', 10 | '1FB', 11 | '1NB', 12 | '2TW', 13 | '2BB', 14 | '2FB', 15 | '2NB', 16 | '2YW', 17 | '3TR', 18 | '3BW', 19 | '3FW', 20 | '3NW', 21 | '3YR', 22 | '4FR', 23 | '4KR', 24 | ], 25 | faction: 'Rebel Alliance', 26 | stats: [ 27 | { arc: 'Front Arc', type: 'attack', value: 3 }, 28 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 29 | { type: 'agility', value: 1 }, 30 | { type: 'hull', value: 6 }, 31 | { type: 'shields', value: 3 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { difficulty: 'Red', type: 'Barrel Roll' }, 37 | ], 38 | icon: 39 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_Arc-170.png', 40 | pilots: [ 41 | { 42 | name: 'Garven Dreis', 43 | caption: 'Red Leader', 44 | initiative: 4, 45 | limited: 1, 46 | cost: 4, 47 | xws: 'garvendreis', 48 | ability: 49 | 'After you spend a focus token, you may choose 1 friendly ship at range 1-3. That ship gains 1 focus token.', 50 | slots: [ 51 | 'Talent', 52 | 'Cannon', 53 | 'Missile', 54 | 'Gunner', 55 | 'Astromech', 56 | 'Modification', 57 | ], 58 | ffg: 66, 59 | standard: true, 60 | epic: true, 61 | loadout: 7, 62 | extended: true, 63 | image: 'https://infinitearenas.com/xw2/images/pilots/garvendreis.png', 64 | artwork: 65 | 'https://infinitearenas.com/xw2/images/artwork/pilots/garvendreis.png', 66 | }, 67 | { 68 | name: 'Ibtisam', 69 | caption: 'Survivor of Endor', 70 | initiative: 3, 71 | limited: 1, 72 | cost: 4, 73 | xws: 'ibtisam', 74 | ability: 75 | 'After you fully execute a maneuver, if you are stressed, you may roll 1 attack die. On a [Hit] or [Critical Hit] result, remove 1 stress token.', 76 | slots: ['Talent', 'Torpedo', 'Gunner', 'Astromech', 'Modification'], 77 | ffg: 68, 78 | standard: true, 79 | epic: true, 80 | loadout: 9, 81 | extended: true, 82 | image: 'https://infinitearenas.com/xw2/images/pilots/ibtisam.png', 83 | artwork: 84 | 'https://infinitearenas.com/xw2/images/artwork/pilots/ibtisam.png', 85 | }, 86 | { 87 | name: 'Norra Wexley', 88 | caption: 'Gold Nine', 89 | initiative: 5, 90 | limited: 1, 91 | cost: 5, 92 | xws: 'norrawexley', 93 | ability: 94 | 'While you defend, if there is an enemy ship at range 0-1, add 1 [Evade] result to your dice results.', 95 | slots: ['Talent', 'Torpedo', 'Gunner', 'Astromech', 'Modification'], 96 | ffg: 65, 97 | standard: true, 98 | epic: true, 99 | loadout: 8, 100 | extended: true, 101 | image: 'https://infinitearenas.com/xw2/images/pilots/norrawexley.png', 102 | artwork: 103 | 'https://infinitearenas.com/xw2/images/artwork/pilots/norrawexley.png', 104 | }, 105 | { 106 | name: 'Shara Bey', 107 | caption: 'Green Four', 108 | initiative: 4, 109 | limited: 1, 110 | cost: 4, 111 | xws: 'sharabey', 112 | ability: 113 | 'While you defend or perform a primary attack, you may spend 1 lock you have on the enemy ship to add 1 [Focus] result to your dice results.', 114 | slots: [ 115 | 'Talent', 116 | 'Torpedo', 117 | 'Missile', 118 | 'Gunner', 119 | 'Astromech', 120 | 'Modification', 121 | ], 122 | ffg: 67, 123 | standard: true, 124 | epic: true, 125 | loadout: 8, 126 | extended: true, 127 | image: 'https://infinitearenas.com/xw2/images/pilots/sharabey.png', 128 | artwork: 129 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sharabey.png', 130 | }, 131 | ], 132 | }; 133 | 134 | export default t; 135 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/attack-shuttle.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Attack Shuttle', 5 | xws: 'attackshuttle', 6 | ffg: 32, 7 | size: 'Small', 8 | dial: [ 9 | '1TR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '1YR', 14 | '2TW', 15 | '2BW', 16 | '2FB', 17 | '2NW', 18 | '2YW', 19 | '3TR', 20 | '3BW', 21 | '3FW', 22 | '3NW', 23 | '3YR', 24 | '4FW', 25 | '4KR', 26 | ], 27 | faction: 'Rebel Alliance', 28 | stats: [ 29 | { arc: 'Front Arc', type: 'attack', value: 3 }, 30 | { type: 'agility', value: 2 }, 31 | { type: 'hull', value: 3 }, 32 | { type: 'shields', value: 1 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'White', type: 'Evade' }, 37 | { 38 | difficulty: 'White', 39 | linked: { difficulty: 'Red', type: 'Evade' }, 40 | type: 'Barrel Roll', 41 | }, 42 | ], 43 | ability: { 44 | name: 'Locked and Loaded', 45 | text: 46 | 'While you are docked, after your carrier ship performs a primary [Front Arc] or [Turret] attack, it may perform a bonus primary [Rear Arc] attack.', 47 | }, 48 | icon: 49 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_AttackShuttle.png', 50 | pilots: [ 51 | { 52 | name: '“Zeb” Orrelios', 53 | caption: 'Spectre-4', 54 | initiative: 2, 55 | limited: 1, 56 | cost: 3, 57 | xws: 'zeborrelios', 58 | ability: 59 | 'While you defend, [Critical Hit] results are neutralized before [Hit] results.', 60 | slots: ['Talent', 'Turret', 'Crew', 'Modification', 'Title'], 61 | ffg: 37, 62 | standard: false, 63 | epic: true, 64 | keywords: ['Spectre'], 65 | loadout: 10, 66 | extended: true, 67 | image: 'https://infinitearenas.com/xw2/images/pilots/zeborrelios.png', 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/zeborrelios.png', 70 | }, 71 | { 72 | name: 'Ezra Bridger', 73 | caption: 'Spectre-6', 74 | initiative: 3, 75 | limited: 1, 76 | cost: 4, 77 | xws: 'ezrabridger', 78 | ability: 79 | 'While you defend or perform an attack, if you are stressed, you may spend 1 [Force] to change up to 2 of your [Focus] results to [Evade] or [Hit] results.', 80 | force: { value: 1, recovers: 1, side: ['light'] }, 81 | slots: ['Force Power', 'Turret', 'Crew', 'Modification', 'Title'], 82 | ffg: 36, 83 | standard: false, 84 | epic: true, 85 | loadout: 7, 86 | extended: true, 87 | keywords: ['Light Side', 'Spectre'], 88 | image: 'https://infinitearenas.com/xw2/images/pilots/ezrabridger.png', 89 | artwork: 90 | 'https://infinitearenas.com/xw2/images/artwork/pilots/ezrabridger.png', 91 | }, 92 | { 93 | name: 'Hera Syndulla', 94 | caption: 'Spectre-2', 95 | initiative: 5, 96 | limited: 1, 97 | cost: 4, 98 | xws: 'herasyndulla', 99 | ability: 100 | 'After you reveal a red or blue maneuver, you may set your dial to another maneuver of the same difficulty.', 101 | slots: ['Talent', 'Turret', 'Crew', 'Modification', 'Title'], 102 | ffg: 34, 103 | standard: false, 104 | epic: true, 105 | keywords: ['Spectre'], 106 | loadout: 9, 107 | extended: true, 108 | image: 'https://infinitearenas.com/xw2/images/pilots/herasyndulla.png', 109 | artwork: 110 | 'https://infinitearenas.com/xw2/images/artwork/pilots/herasyndulla.png', 111 | }, 112 | { 113 | name: 'Sabine Wren', 114 | caption: 'Spectre-5', 115 | initiative: 3, 116 | limited: 1, 117 | cost: 4, 118 | xws: 'sabinewren', 119 | ability: 120 | 'Before you activate, you may perform a [Barrel Roll] or [Boost] action.', 121 | slots: ['Talent', 'Turret', 'Crew', 'Modification', 'Title'], 122 | ffg: 35, 123 | standard: false, 124 | epic: true, 125 | loadout: 6, 126 | extended: true, 127 | keywords: ['Mandalorian', 'Spectre'], 128 | image: 'https://infinitearenas.com/xw2/images/pilots/sabinewren.png', 129 | artwork: 130 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sabinewren.png', 131 | }, 132 | ], 133 | }; 134 | 135 | export default t; 136 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/auzituck-gunship.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Auzituck Gunship', 5 | xws: 'auzituckgunship', 6 | ffg: 6, 7 | size: 'Small', 8 | dial: [ 9 | '0OR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '2TW', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YW', 18 | '3TW', 19 | '3BW', 20 | '3FB', 21 | '3NW', 22 | '3YW', 23 | '4FW', 24 | ], 25 | faction: 'Rebel Alliance', 26 | stats: [ 27 | { arc: 'Full Front Arc', type: 'attack', value: 3 }, 28 | { type: 'agility', value: 1 }, 29 | { type: 'hull', value: 6 }, 30 | { type: 'shields', value: 2 }, 31 | ], 32 | actions: [ 33 | { difficulty: 'White', type: 'Focus' }, 34 | { difficulty: 'White', type: 'Reinforce' }, 35 | { difficulty: 'Red', type: 'Barrel Roll' }, 36 | ], 37 | icon: 38 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_Auzituck.png', 39 | pilots: [ 40 | { 41 | name: 'Kashyyyk Defender', 42 | initiative: 1, 43 | limited: 0, 44 | cost: 5, 45 | xws: 'kashyyykdefender', 46 | text: 47 | 'Equipped with three wide-range Sureggi twin laser cannons, the Auzituck gunship acts as a powerful deterrent to slaver operations in the Kashyyyk system.', 48 | slots: ['Crew', 'Modification'], 49 | ffg: 33, 50 | standard: false, 51 | epic: true, 52 | loadout: 6, 53 | extended: true, 54 | image: 55 | 'https://infinitearenas.com/xw2/images/pilots/kashyyykdefender.png', 56 | artwork: 57 | 'https://infinitearenas.com/xw2/images/artwork/pilots/kashyyykdefender.png', 58 | }, 59 | { 60 | name: 'Lowhhrick', 61 | caption: 'Escaped Gladiator', 62 | initiative: 3, 63 | limited: 1, 64 | cost: 5, 65 | xws: 'lowhhrick', 66 | ability: 67 | 'After a friendly ship at range 0-1 becomes the defender, you may spend 1 reinforce token. If you do, that ship gains 1 evade token.', 68 | slots: ['Talent', 'Crew', 'Crew', 'Modification'], 69 | ffg: 32, 70 | standard: false, 71 | epic: true, 72 | loadout: 10, 73 | extended: true, 74 | image: 'https://infinitearenas.com/xw2/images/pilots/lowhhrick.png', 75 | artwork: 76 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lowhhrick.png', 77 | }, 78 | { 79 | name: 'Wullffwarro', 80 | caption: 'Wookiee Chief', 81 | initiative: 4, 82 | limited: 1, 83 | cost: 5, 84 | xws: 'wullffwarro', 85 | ability: 86 | 'While you perform a primary attack, if you are damaged, you may roll 1 additional attack die.', 87 | slots: ['Talent', 'Crew', 'Crew', 'Modification'], 88 | ffg: 31, 89 | standard: false, 90 | epic: true, 91 | loadout: 11, 92 | extended: true, 93 | image: 'https://infinitearenas.com/xw2/images/pilots/wullffwarro.png', 94 | artwork: 95 | 'https://infinitearenas.com/xw2/images/artwork/pilots/wullffwarro.png', 96 | }, 97 | ], 98 | }; 99 | 100 | export default t; 101 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/btl-s8-k-wing.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'BTL-S8 K-wing', 5 | xws: 'btls8kwing', 6 | ffg: 30, 7 | size: 'Medium', 8 | dial: [ 9 | '1BB', 10 | '1FB', 11 | '1NB', 12 | '2TW', 13 | '2BW', 14 | '2FB', 15 | '2NW', 16 | '2YW', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | ], 21 | faction: 'Rebel Alliance', 22 | stats: [ 23 | { arc: 'Double Turret Arc', type: 'attack', value: 2 }, 24 | { type: 'agility', value: 1 }, 25 | { type: 'hull', value: 6 }, 26 | { type: 'shields', value: 3 }, 27 | ], 28 | actions: [ 29 | { difficulty: 'White', type: 'Focus' }, 30 | { difficulty: 'White', type: 'Lock' }, 31 | { difficulty: 'White', type: 'SLAM' }, 32 | { difficulty: 'White', type: 'Rotate Arc' }, 33 | { difficulty: 'White', type: 'Reload' }, 34 | ], 35 | icon: 36 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_K-wing.png', 37 | pilots: [ 38 | { 39 | name: 'Esege Tuketu', 40 | caption: 'Selfless Hero', 41 | initiative: 3, 42 | limited: 1, 43 | cost: 5, 44 | xws: 'esegetuketu', 45 | ability: 46 | 'While a friendly ship at range 0-2 defends or performs an attack, it may spend your focus tokens as if that ship has them.', 47 | slots: [ 48 | 'Torpedo', 49 | 'Missile', 50 | 'Missile', 51 | 'Gunner', 52 | 'Crew', 53 | 'Device', 54 | 'Modification', 55 | ], 56 | ffg: 63, 57 | standard: false, 58 | epic: true, 59 | loadout: 16, 60 | extended: true, 61 | image: 'https://infinitearenas.com/xw2/images/pilots/esegetuketu.png', 62 | artwork: 63 | 'https://infinitearenas.com/xw2/images/artwork/pilots/esegetuketu.png', 64 | }, 65 | { 66 | name: 'Miranda Doni', 67 | caption: 'Heavy Hitter', 68 | initiative: 4, 69 | limited: 1, 70 | cost: 5, 71 | xws: 'mirandadoni', 72 | ability: 73 | 'While you perform a primary attack, you may either spend 1 shield to roll 1 additional attack die or, if you are not shielded, you may roll 1 fewer attack die to recover 1 shield.', 74 | slots: [ 75 | 'Torpedo', 76 | 'Missile', 77 | 'Gunner', 78 | 'Crew', 79 | 'Device', 80 | 'Device', 81 | 'Modification', 82 | ], 83 | ffg: 62, 84 | standard: false, 85 | epic: true, 86 | loadout: 14, 87 | extended: true, 88 | image: 'https://infinitearenas.com/xw2/images/pilots/mirandadoni.png', 89 | artwork: 90 | 'https://infinitearenas.com/xw2/images/artwork/pilots/mirandadoni.png', 91 | }, 92 | { 93 | name: 'Warden Squadron Pilot', 94 | initiative: 2, 95 | limited: 0, 96 | cost: 5, 97 | xws: 'wardensquadronpilot', 98 | text: 99 | "Koensayr Manufacturing's K-wing boasts an advanced SubLight Acceleration Motor and an unprecedented 18 hard points, granting it unrivaled speed and firepower.", 100 | slots: ['Torpedo', 'Missile', 'Gunner', 'Device', 'Device'], 101 | ffg: 64, 102 | standard: false, 103 | epic: true, 104 | loadout: 7, 105 | extended: true, 106 | image: 107 | 'https://infinitearenas.com/xw2/images/pilots/wardensquadronpilot.png', 108 | artwork: 109 | 'https://infinitearenas.com/xw2/images/artwork/pilots/wardensquadronpilot.png', 110 | }, 111 | ], 112 | }; 113 | 114 | export default t; 115 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/cr90-corellian-corvette.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'CR90 Corellian Corvette', 5 | xws: 'cr90corelliancorvette', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FW', 14 | '2BB', 15 | '2NB', 16 | '2FB', 17 | '3NR', 18 | '3FB', 19 | '3BR', 20 | '4FR', 21 | '5FR', 22 | ], 23 | faction: 'Rebel Alliance', 24 | stats: [ 25 | { type: 'attack', arc: 'Left Arc', value: 4 }, 26 | { type: 'attack', arc: 'Right Arc', value: 4 }, 27 | { type: 'hull', value: 18 }, 28 | { type: 'shields', value: 7, recovers: 2 }, 29 | { type: 'energy', value: 7, recovers: 2 }, 30 | ], 31 | actions: [ 32 | { type: 'Focus', difficulty: 'White' }, 33 | { type: 'Reinforce', difficulty: 'White' }, 34 | { type: 'Lock', difficulty: 'White' }, 35 | { type: 'Coordinate', difficulty: 'Red' }, 36 | { type: 'Jam', difficulty: 'Red' }, 37 | ], 38 | ability: { 39 | name: 'Broadside Batteries', 40 | text: 'You can acquire locks and perform primary attacks at range 1-4.', 41 | }, 42 | pilots: [ 43 | { 44 | name: 'Alderaanian Guard', 45 | text: 46 | 'A craft used since before the Clone Wars, the CR90 corvette is favored by the Royal House of Alderaan for its versatility.', 47 | initiative: 8, 48 | engagement: 0, 49 | limited: 0, 50 | cost: 134, 51 | xws: 'alderaanianguard', 52 | slots: [ 53 | 'Command', 54 | 'Hardpoint', 55 | 'Hardpoint', 56 | 'Crew', 57 | 'Crew', 58 | 'Gunner', 59 | 'Team', 60 | 'Team', 61 | 'Cargo', 62 | 'Title', 63 | ], 64 | standard: false, 65 | extended: false, 66 | epic: true, 67 | ffg: 706, 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/alderaanianguard.png', 70 | image: 71 | 'https://infinitearenas.com/xw2/images/pilots/alderaanianguard.png', 72 | }, 73 | ], 74 | ffg: 78, 75 | icon: 76 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_CR90.png', 77 | }; 78 | 79 | export default t; 80 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/e-wing.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'E-wing', 5 | xws: 'ewing', 6 | ffg: 40, 7 | size: 'Small', 8 | dial: [ 9 | '1TR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '1YR', 14 | '2TW', 15 | '2BW', 16 | '2FB', 17 | '2NW', 18 | '2YW', 19 | '3LR', 20 | '3TW', 21 | '3BW', 22 | '3FB', 23 | '3NW', 24 | '3YW', 25 | '3PR', 26 | '4FB', 27 | '4KR', 28 | '5FW', 29 | ], 30 | faction: 'Rebel Alliance', 31 | stats: [ 32 | { arc: 'Front Arc', type: 'attack', value: 3 }, 33 | { type: 'agility', value: 3 }, 34 | { type: 'hull', value: 3 }, 35 | { type: 'shields', value: 3 }, 36 | ], 37 | actions: [ 38 | { difficulty: 'White', type: 'Focus' }, 39 | { difficulty: 'White', type: 'Evade' }, 40 | { difficulty: 'White', type: 'Lock' }, 41 | { 42 | difficulty: 'White', 43 | linked: { difficulty: 'Red', type: 'Lock' }, 44 | type: 'Barrel Roll', 45 | }, 46 | { 47 | difficulty: 'White', 48 | linked: { difficulty: 'Red', type: 'Lock' }, 49 | type: 'Boost', 50 | }, 51 | ], 52 | ability: { 53 | name: 'Experimental Scanners', 54 | text: 55 | 'You can acquire locks beyond range 3. You cannot acquire locks at range 1.', 56 | }, 57 | icon: 58 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_E-wing.png', 59 | pilots: [ 60 | { 61 | name: 'Corran Horn', 62 | caption: 'Tenacious Investigator', 63 | initiative: 5, 64 | limited: 1, 65 | cost: 6, 66 | xws: 'corranhorn', 67 | ability: 68 | 'At initiative 0, you may perform a bonus primary attack against an enemy ship in your [Bullseye Arc]. If you do, at the start of the next Planning Phase, gain 1 disarm token.', 69 | slots: [ 70 | 'Talent', 71 | 'Tech', 72 | 'Sensor', 73 | 'Sensor', 74 | 'Torpedo', 75 | 'Astromech', 76 | 'Modification', 77 | ], 78 | ffg: 50, 79 | standard: false, 80 | epic: true, 81 | loadout: 20, 82 | extended: true, 83 | image: 'https://infinitearenas.com/xw2/images/pilots/corranhorn.png', 84 | artwork: 85 | 'https://infinitearenas.com/xw2/images/artwork/pilots/corranhorn.png', 86 | }, 87 | { 88 | name: 'Gavin Darklighter', 89 | caption: 'Bold Wingman', 90 | initiative: 4, 91 | limited: 1, 92 | cost: 5, 93 | xws: 'gavindarklighter', 94 | ability: 95 | 'While a friendly ship performs an attack, if the defender is in your [Front Arc], the attacker may change 1 [Hit] result to a [Critical Hit] result.', 96 | slots: [ 97 | 'Talent', 98 | 'Tech', 99 | 'Sensor', 100 | 'Torpedo', 101 | 'Astromech', 102 | 'Modification', 103 | ], 104 | ffg: 51, 105 | standard: false, 106 | epic: true, 107 | loadout: 18, 108 | extended: true, 109 | image: 110 | 'https://infinitearenas.com/xw2/images/pilots/gavindarklighter.png', 111 | artwork: 112 | 'https://infinitearenas.com/xw2/images/artwork/pilots/gavindarklighter.png', 113 | }, 114 | { 115 | name: 'Knave Squadron Escort', 116 | initiative: 2, 117 | limited: 0, 118 | cost: 5, 119 | xws: 'knavesquadronescort', 120 | text: 121 | 'Designed to combine the best features of the X-wing series with the A-wing series, the E-wing boasts superior firepower, speed, and maneuverability.', 122 | slots: ['Sensor', 'Tech', 'Astromech', 'Modification'], 123 | ffg: 53, 124 | standard: false, 125 | epic: true, 126 | loadout: 14, 127 | extended: true, 128 | image: 129 | 'https://infinitearenas.com/xw2/images/pilots/knavesquadronescort.png', 130 | artwork: 131 | 'https://infinitearenas.com/xw2/images/artwork/pilots/knavesquadronescort.png', 132 | }, 133 | { 134 | name: 'Rogue Squadron Escort', 135 | initiative: 4, 136 | limited: 0, 137 | cost: 5, 138 | xws: 'roguesquadronescort', 139 | text: 140 | "The elite pilots of Rogue Squadron are among the Rebellion's very best.", 141 | slots: ['Sensor', 'Torpedo', 'Astromech', 'Modification'], 142 | ffg: 52, 143 | standard: false, 144 | epic: true, 145 | loadout: 12, 146 | extended: true, 147 | image: 148 | 'https://infinitearenas.com/xw2/images/pilots/roguesquadronescort.png', 149 | artwork: 150 | 'https://infinitearenas.com/xw2/images/artwork/pilots/roguesquadronescort.png', 151 | }, 152 | ], 153 | }; 154 | 155 | export default t; 156 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/fang-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Fang Fighter', 5 | xws: 'fangfighter', 6 | ffg: 36, 7 | size: 'Small', 8 | dial: [ 9 | '1TW', 10 | '1YW', 11 | '2ER', 12 | '2TB', 13 | '2BB', 14 | '2FB', 15 | '2NB', 16 | '2YB', 17 | '2RR', 18 | '3TW', 19 | '3BW', 20 | '3FB', 21 | '3NW', 22 | '3YW', 23 | '4FW', 24 | '4KR', 25 | '5FW', 26 | ], 27 | faction: 'Rebel Alliance', 28 | stats: [ 29 | { arc: 'Front Arc', type: 'attack', value: 3 }, 30 | { type: 'agility', value: 3 }, 31 | { type: 'hull', value: 4 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { 37 | difficulty: 'White', 38 | linked: { difficulty: 'Red', type: 'Focus' }, 39 | type: 'Barrel Roll', 40 | }, 41 | { 42 | difficulty: 'White', 43 | linked: { difficulty: 'Red', type: 'Focus' }, 44 | type: 'Boost', 45 | }, 46 | ], 47 | ability: { 48 | name: 'Concordia Faceoff', 49 | text: 50 | "While you defend, if the attack range is 1 and you are in the attacker's [Front Arc], change 1 result to an [Evade] result.", 51 | }, 52 | icon: 53 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_FangFighter.png', 54 | pilots: [ 55 | { 56 | name: 'Fenn Rau', 57 | caption: 'Mandalorian Protector', 58 | xws: 'fennrau-fangfighter', 59 | initiative: 6, 60 | limited: 1, 61 | cost: 5, 62 | loadout: 9, 63 | ability: 64 | 'Before a friendly ship at range 1-2 engages, if there is an enemy ship in its [Front Arc] at range 1, that friendly ship may remove 1 non-lock red token.', 65 | image: 66 | 'https://infinitearenas.com/xw2/images/pilots/fennrau-rebel-fang.png', 67 | slots: ['Talent', 'Talent', 'Torpedo', 'Modification', 'Modification'], 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/fennrau-rebel-fang.png', 70 | standard: true, 71 | extended: true, 72 | epic: true, 73 | keywords: ['Mandalorian'], 74 | }, 75 | { 76 | name: 'Bodica Venj', 77 | caption: 'Wrathful Warrior', 78 | initiative: 4, 79 | limited: 1, 80 | xws: 'bodicavenj', 81 | ability: 82 | 'After another friendly ship defends, if you are not depleted, you may perform a bonus primary attack against the attacker. If you do, after performing that attack, gain 1 deplete token.', 83 | slots: ['Talent', 'Talent', 'Torpedo', 'Modification', 'Modification'], 84 | keywords: ['Mandalorian'], 85 | cost: 4, 86 | epic: true, 87 | standard: true, 88 | loadout: 7, 89 | extended: true, 90 | image: 'https://infinitearenas.com/xw2/images/pilots/bodicavenj.png', 91 | artwork: 92 | 'https://infinitearenas.com/xw2/images/artwork/pilots/bodicavenj.png', 93 | }, 94 | { 95 | name: 'Dirk Ullodin', 96 | caption: 'Aspiring Commando', 97 | initiative: 3, 98 | limited: 1, 99 | xws: 'dirkullodin', 100 | ability: 101 | 'After you fully execute a red maneuver or perform a red action, you may acquire a lock on an enemy ship in your [Front Arc] at range 1.', 102 | slots: ['Torpedo', 'Modification', 'Modification'], 103 | keywords: ['Mandalorian'], 104 | cost: 4, 105 | epic: true, 106 | standard: true, 107 | loadout: 9, 108 | extended: true, 109 | image: 'https://infinitearenas.com/xw2/images/pilots/dirkullodin.png', 110 | artwork: 111 | 'https://infinitearenas.com/xw2/images/artwork/pilots/dirkullodin.png', 112 | }, 113 | { 114 | name: 'Clan Wren Volunteer', 115 | caption: 'Unlikely Ally', 116 | initiative: 3, 117 | limited: 2, 118 | xws: 'clanwrenvolunteer', 119 | ability: 120 | 'While you perform an attack at range 1, if the speed of your revealed maneuver matches that of a friendly ship at range 1, you may reroll 1 attack die.', 121 | slots: ['Talent', 'Torpedo', 'Modification', 'Modification'], 122 | keywords: ['Mandalorian'], 123 | cost: 4, 124 | epic: true, 125 | standard: true, 126 | loadout: 12, 127 | extended: true, 128 | image: 129 | 'https://infinitearenas.com/xw2/images/pilots/clanwrenvolunteer.png', 130 | artwork: 131 | 'https://infinitearenas.com/xw2/images/artwork/pilots/clanwrenvolunteer.png', 132 | }, 133 | ], 134 | }; 135 | 136 | export default t; 137 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/gauntlet-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gauntlet Fighter', 5 | xws: 'gauntletfighter', 6 | size: 'Large', 7 | dial: [ 8 | '0OR', 9 | '1BB', 10 | '1NB', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TR', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | '3YR', 21 | '4FW', 22 | ], 23 | faction: 'Rebel Alliance', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 9 }, 29 | { type: 'shields', value: 2 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Reinforce' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | ], 37 | pilots: [ 38 | { 39 | xws: 'chopper-gauntletfighter', 40 | name: '"Chopper"', 41 | ability: 42 | 'At the start of the Engagement Phase, each enemy ship at range 0 gains 2 jam tokens.', 43 | cost: 6, 44 | loadout: 10, 45 | initiative: 2, 46 | limited: 1, 47 | standard: true, 48 | extended: true, 49 | epic: true, 50 | slots: [ 51 | 'Crew', 52 | 'Gunner', 53 | 'Device', 54 | 'Modification', 55 | 'Modification', 56 | 'Configuration', 57 | 'Title', 58 | 'Illicit', 59 | ], 60 | caption: 'Spectre-3', 61 | keywords: ['Droid', 'Spectre'], 62 | image: 63 | 'https://infinitearenas.com/xw2/images/pilots/chopper-gauntletfighter.png', 64 | artwork: 65 | 'https://infinitearenas.com/xw2/images/artwork/pilots/chopper-gauntletfighter.png', 66 | }, 67 | { 68 | xws: 'ezrabridger-gauntletfighter', 69 | name: 'Ezra Bridger', 70 | cost: 6, 71 | loadout: 12, 72 | initiative: 3, 73 | limited: 1, 74 | ability: 75 | 'While you defend or perform an attack, if you are stressed, you may spend 1 [Force] to change up to 2 of your [Focus] results to [Evade] or [Hit] results.', 76 | force: { side: ['light'], value: 1, recovers: 1 }, 77 | standard: true, 78 | extended: true, 79 | epic: true, 80 | slots: [ 81 | 'Force Power', 82 | 'Talent', 83 | 'Crew', 84 | 'Gunner', 85 | 'Device', 86 | 'Illicit', 87 | 'Modification', 88 | 'Modification', 89 | 'Configuration', 90 | 'Title', 91 | ], 92 | caption: 'Spectre-6', 93 | keywords: ['Light Side', 'Spectre'], 94 | image: 95 | 'https://infinitearenas.com/xw2/images/pilots/ezrabridger-gauntletfighter.png', 96 | artwork: 97 | 'https://infinitearenas.com/xw2/images/artwork/pilots/ezrabridger-gauntletfighter.png', 98 | }, 99 | { 100 | xws: 'mandalorianresistancepilot', 101 | name: 'Mandalorian Resistance Pilot', 102 | cost: 7, 103 | loadout: 10, 104 | initiative: 2, 105 | limited: 0, 106 | standard: true, 107 | extended: true, 108 | epic: true, 109 | slots: [ 110 | 'Talent', 111 | 'Crew', 112 | 'Gunner', 113 | 'Device', 114 | 'Modification', 115 | 'Configuration', 116 | ], 117 | keywords: ['Mandalorian'], 118 | caption: 'Clan Loyalist', 119 | image: 120 | 'https://infinitearenas.com/xw2/images/pilots/mandalorianresistancepilot.png', 121 | artwork: 122 | 'https://infinitearenas.com/xw2/images/artwork/pilots/mandalorianresistancepilot.png', 123 | }, 124 | ], 125 | }; 126 | 127 | export default t; 128 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/gr-75-medium-transport.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'GR-75 Medium Transport', 5 | xws: 'gr75mediumtransport', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BB', 12 | '1NB', 13 | '1FB', 14 | '2BW', 15 | '2NW', 16 | '2FW', 17 | '3FR', 18 | '4FR', 19 | ], 20 | faction: 'Rebel Alliance', 21 | stats: [], 22 | actions: [], 23 | ability: { 24 | name: 'Resupply Craft', 25 | text: 26 | 'After another friendly ship at range 0-1 performs an action, you may spend 1 [Energy]. If you do, it removes 1 orange or red token, or recovers 1 shield.', 27 | }, 28 | pilots: [ 29 | { 30 | name: 'Echo Base Evacuees', 31 | text: 32 | "The GR-75 medium transport acquitted itself well at battles such as the evacuation of Hoth, where several of these ships were pivotal to the Rebel forces' escape.", 33 | initiative: 7, 34 | engagement: 1, 35 | limited: 0, 36 | cost: 65, 37 | xws: 'echobaseevacuees', 38 | slots: [ 39 | 'Command', 40 | 'Hardpoint', 41 | 'Turret', 42 | 'Crew', 43 | 'Crew', 44 | 'Team', 45 | 'Cargo', 46 | 'Cargo', 47 | 'Title', 48 | ], 49 | standard: false, 50 | extended: false, 51 | epic: true, 52 | ffg: 709, 53 | artwork: 54 | 'https://infinitearenas.com/xw2/images/artwork/pilots/echobaseevacuees.png', 55 | image: 56 | 'https://infinitearenas.com/xw2/images/pilots/echobaseevacuees.png', 57 | }, 58 | ], 59 | ffg: 80, 60 | icon: 61 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_GR-75.png', 62 | }; 63 | 64 | export default t; 65 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/hwk-290-light-freighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'HWK-290 Light Freighter', 5 | xws: 'hwk290lightfreighter', 6 | ffg: 34, 7 | size: 'Small', 8 | dial: [ 9 | '0OR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '2TW', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YW', 18 | '3TR', 19 | '3BW', 20 | '3FB', 21 | '3NW', 22 | '3YR', 23 | '4FW', 24 | ], 25 | faction: 'Rebel Alliance', 26 | stats: [ 27 | { arc: 'Single Turret Arc', type: 'attack', value: 2 }, 28 | { type: 'agility', value: 2 }, 29 | { type: 'hull', value: 3 }, 30 | { type: 'shields', value: 2 }, 31 | ], 32 | actions: [ 33 | { 34 | difficulty: 'White', 35 | linked: { difficulty: 'Red', type: 'Rotate Arc' }, 36 | type: 'Focus', 37 | }, 38 | { 39 | difficulty: 'White', 40 | linked: { difficulty: 'Red', type: 'Rotate Arc' }, 41 | type: 'Lock', 42 | }, 43 | { difficulty: 'Red', type: 'Boost' }, 44 | { difficulty: 'White', type: 'Rotate Arc' }, 45 | { difficulty: 'Red', type: 'Jam' }, 46 | ], 47 | icon: 48 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_HWK-290.png', 49 | pilots: [ 50 | { 51 | name: 'Jan Ors', 52 | caption: 'Espionage Expert', 53 | initiative: 5, 54 | limited: 1, 55 | cost: 6, 56 | xws: 'janors', 57 | ability: 58 | 'While a friendly ship in your firing arc performs a primary attack, if you are not stressed, you may gain 1 stress token. If you do, that ship may roll 1 additional attack die.', 59 | slots: [ 60 | 'Talent', 61 | 'Crew', 62 | 'Device', 63 | 'Device', 64 | 'Modification', 65 | 'Modification', 66 | 'Title', 67 | ], 68 | ffg: 42, 69 | standard: true, 70 | epic: true, 71 | keywords: ['Freighter'], 72 | loadout: 10, 73 | extended: true, 74 | image: 'https://infinitearenas.com/xw2/images/pilots/janors.png', 75 | artwork: 76 | 'https://infinitearenas.com/xw2/images/artwork/pilots/janors.png', 77 | }, 78 | { 79 | name: 'Kyle Katarn', 80 | caption: 'Relentless Operative', 81 | initiative: 3, 82 | limited: 1, 83 | cost: 5, 84 | xws: 'kylekatarn', 85 | ability: 86 | 'At the start of the Engagement Phase, you may transfer 1 of your focus tokens to a friendly ship in your firing arc.', 87 | slots: ['Talent', 'Talent', 'Crew', 'Device', 'Modification', 'Title'], 88 | ffg: 43, 89 | standard: true, 90 | epic: true, 91 | keywords: ['Freighter'], 92 | loadout: 8, 93 | extended: true, 94 | image: 'https://infinitearenas.com/xw2/images/pilots/kylekatarn.png', 95 | artwork: 96 | 'https://infinitearenas.com/xw2/images/artwork/pilots/kylekatarn.png', 97 | }, 98 | { 99 | name: 'Rebel Scout', 100 | initiative: 2, 101 | limited: 0, 102 | cost: 4, 103 | xws: 'rebelscout', 104 | text: 105 | 'Designed to look like a bird in flight by the Corellian Engineering Corporation, "hawk" series ships are exemplary transport craft. Swift and rugged, the HWK-290 is often employed by Rebel agents as a mobile base of operations.', 106 | slots: ['Device', 'Modification'], 107 | ffg: 45, 108 | standard: true, 109 | epic: true, 110 | keywords: ['Freighter'], 111 | loadout: 6, 112 | extended: true, 113 | image: 'https://infinitearenas.com/xw2/images/pilots/rebelscout.png', 114 | artwork: 115 | 'https://infinitearenas.com/xw2/images/artwork/pilots/rebelscout.png', 116 | }, 117 | { 118 | name: 'Roark Garnet', 119 | caption: 'Good-Hearted Smuggler', 120 | initiative: 4, 121 | limited: 1, 122 | cost: 5, 123 | xws: 'roarkgarnet', 124 | ability: 125 | 'At the start of the Engagement Phase, you may choose 1 ship in your firing arc. If you do, it engages at initiative 7 instead of its standard initiative value this phase.', 126 | slots: [ 127 | 'Talent', 128 | 'Crew', 129 | 'Device', 130 | 'Modification', 131 | 'Modification', 132 | 'Title', 133 | ], 134 | ffg: 44, 135 | standard: true, 136 | epic: true, 137 | keywords: ['Freighter'], 138 | loadout: 12, 139 | extended: true, 140 | image: 'https://infinitearenas.com/xw2/images/pilots/roarkgarnet.png', 141 | artwork: 142 | 'https://infinitearenas.com/xw2/images/artwork/pilots/roarkgarnet.png', 143 | }, 144 | ], 145 | }; 146 | 147 | export default t; 148 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import asf01bwing from './a-sf-01-b-wing'; 3 | import arc170starfighter from './arc-170-starfighter'; 4 | import attackshuttle from './attack-shuttle'; 5 | import auzituckgunship from './auzituck-gunship'; 6 | import btla4ywing from './btl-a4-y-wing'; 7 | import btls8kwing from './btl-s8-k-wing'; 8 | import cr90corelliancorvette from './cr90-corellian-corvette'; 9 | import ewing from './e-wing'; 10 | import gr75mediumtransport from './gr-75-medium-transport'; 11 | import hwk290lightfreighter from './hwk-290-light-freighter'; 12 | import modifiedyt1300lightfreighter from './modified-yt-1300-light-freighter'; 13 | import rz1awing from './rz-1-a-wing'; 14 | import sheathipedeclassshuttle from './sheathipede-class-shuttle'; 15 | import t65xwing from './t-65-x-wing'; 16 | import tielnfighter from './tie-ln-fighter'; 17 | import ut60duwing from './ut-60d-u-wing'; 18 | import vcx100lightfreighter from './vcx-100-light-freighter'; 19 | import yt2400lightfreighter from './yt-2400-light-freighter'; 20 | import z95af4headhunter from './z-95-af4-headhunter'; 21 | import fangfighter from './fang-fighter'; 22 | import gauntletfighter from './gauntlet-fighter'; 23 | 24 | const ships: { [s: string]: ShipType } = { 25 | asf01bwing, 26 | arc170starfighter, 27 | attackshuttle, 28 | auzituckgunship, 29 | btla4ywing, 30 | btls8kwing, 31 | cr90corelliancorvette, 32 | ewing, 33 | fangfighter, 34 | gauntletfighter, 35 | gr75mediumtransport, 36 | hwk290lightfreighter, 37 | modifiedyt1300lightfreighter, 38 | rz1awing, 39 | sheathipedeclassshuttle, 40 | t65xwing, 41 | tielnfighter, 42 | ut60duwing, 43 | vcx100lightfreighter, 44 | yt2400lightfreighter, 45 | z95af4headhunter, 46 | }; 47 | 48 | export default ships; 49 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/tie-ln-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'TIE/ln Fighter', 5 | xws: 'tielnfighter', 6 | ffg: 11, 7 | size: 'Small', 8 | dial: [ 9 | '1TW', 10 | '1YW', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TW', 17 | '3BW', 18 | '3FB', 19 | '3NW', 20 | '3YW', 21 | '3KR', 22 | '4FW', 23 | '4KR', 24 | '5FW', 25 | ], 26 | faction: 'Rebel Alliance', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 2 }, 29 | { type: 'agility', value: 3 }, 30 | { type: 'hull', value: 3 }, 31 | ], 32 | actions: [ 33 | { difficulty: 'White', type: 'Focus' }, 34 | { difficulty: 'White', type: 'Evade' }, 35 | { difficulty: 'White', type: 'Barrel Roll' }, 36 | ], 37 | icon: 38 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_TIEFighter.png', 39 | pilots: [ 40 | { 41 | name: '“Zeb” Orrelios', 42 | caption: 'Spectre-4', 43 | initiative: 2, 44 | limited: 1, 45 | cost: 3, 46 | xws: 'zeborrelios-tielnfighter', 47 | ability: 48 | 'While you defend, [Critical Hit] results are neutralized before [Hit] results.', 49 | slots: ['Crew', 'Modification'], 50 | ffg: 49, 51 | standard: true, 52 | epic: true, 53 | keywords: ['TIE', 'Spectre'], 54 | loadout: 8, 55 | extended: true, 56 | image: 57 | 'https://infinitearenas.com/xw2/images/pilots/zeborrelios-tielnfighter.png', 58 | artwork: 59 | 'https://infinitearenas.com/xw2/images/artwork/pilots/zeborrelios-tielnfighter.png', 60 | }, 61 | { 62 | name: 'Captain Rex', 63 | caption: 'Clone Wars Veteran', 64 | initiative: 2, 65 | limited: 1, 66 | cost: 3, 67 | xws: 'captainrex', 68 | ability: 69 | 'After you perform an attack, assign the Suppressive Fire condition to the defender.', 70 | conditions: ['suppressivefire'], 71 | slots: ['Talent', 'Talent', 'Modification'], 72 | ffg: 48, 73 | standard: true, 74 | epic: true, 75 | keywords: ['Clone', 'TIE'], 76 | loadout: 8, 77 | extended: true, 78 | image: 'https://infinitearenas.com/xw2/images/pilots/captainrex.png', 79 | artwork: 80 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainrex.png', 81 | }, 82 | { 83 | name: 'Ezra Bridger', 84 | caption: 'Spectre-6', 85 | initiative: 3, 86 | limited: 1, 87 | cost: 3, 88 | xws: 'ezrabridger-tielnfighter', 89 | ability: 90 | 'While you defend or perform an attack, if you are stressed, you may spend 1 [Force] to change up to 2 of your [Focus] results to [Evade] or [Hit] results.', 91 | force: { value: 1, recovers: 1, side: ['light'] }, 92 | slots: ['Force Power', 'Crew', 'Modification'], 93 | ffg: 46, 94 | standard: true, 95 | epic: true, 96 | loadout: 6, 97 | extended: true, 98 | keywords: ['Light Side', 'Spectre', 'TIE'], 99 | image: 100 | 'https://infinitearenas.com/xw2/images/pilots/ezrabridger-tielnfighter.png', 101 | artwork: 102 | 'https://infinitearenas.com/xw2/images/artwork/pilots/ezrabridger-tielnfighter.png', 103 | }, 104 | { 105 | name: 'Sabine Wren', 106 | caption: 'Spectre-5', 107 | initiative: 3, 108 | limited: 1, 109 | cost: 2, 110 | xws: 'sabinewren-tielnfighter', 111 | ability: 112 | 'Before you activate, you may perform a [Barrel Roll] or [Boost] action.', 113 | slots: ['Talent', 'Modification'], 114 | ffg: 47, 115 | standard: true, 116 | epic: true, 117 | loadout: 3, 118 | extended: true, 119 | keywords: ['Mandalorian', 'TIE', 'Spectre'], 120 | image: 121 | 'https://infinitearenas.com/xw2/images/pilots/sabinewren-tielnfighter.png', 122 | artwork: 123 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sabinewren-tielnfighter.png', 124 | }, 125 | ], 126 | }; 127 | 128 | export default t; 129 | -------------------------------------------------------------------------------- /src/assets/pilots/rebel-alliance/z-95-af4-headhunter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Z-95-AF4 Headhunter', 5 | xws: 'z95af4headhunter', 6 | ffg: 38, 7 | size: 'Small', 8 | dial: [ 9 | '1BW', 10 | '1FB', 11 | '1NW', 12 | '2TW', 13 | '2BB', 14 | '2FB', 15 | '2NB', 16 | '2YW', 17 | '3TW', 18 | '3BW', 19 | '3FB', 20 | '3NW', 21 | '3YW', 22 | '3KR', 23 | '4FW', 24 | '4KR', 25 | ], 26 | faction: 'Rebel Alliance', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 2 }, 29 | { type: 'agility', value: 2 }, 30 | { type: 'hull', value: 2 }, 31 | { type: 'shields', value: 2 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { difficulty: 'Red', type: 'Barrel Roll' }, 37 | ], 38 | icon: 39 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_Z-95.png', 40 | pilots: [ 41 | { 42 | name: 'Airen Cracken', 43 | caption: 'Intelligence Chief', 44 | initiative: 5, 45 | limited: 1, 46 | cost: 4, 47 | xws: 'airencracken', 48 | ability: 49 | 'After you perform an attack, you may choose 1 friendly ship at range 1. That ship may perform an action, treating it as red.', 50 | slots: ['Talent', 'Sensor', 'Torpedo', 'Modification'], 51 | ffg: 27, 52 | standard: true, 53 | epic: true, 54 | loadout: 11, 55 | extended: true, 56 | image: 'https://infinitearenas.com/xw2/images/pilots/airencracken.png', 57 | artwork: 58 | 'https://infinitearenas.com/xw2/images/artwork/pilots/airencracken.png', 59 | }, 60 | { 61 | name: 'Bandit Squadron Pilot', 62 | initiative: 1, 63 | limited: 0, 64 | cost: 3, 65 | xws: 'banditsquadronpilot', 66 | text: 67 | "The Z-95 Headhunter was the primary inspiration for Incom Corporation's exemplary T-65 X-wing starfighter. Though it is considered outdated by modern standards, it remains a versatile and potent snub fighter.", 68 | slots: ['Missile', 'Modification'], 69 | ffg: 30, 70 | standard: true, 71 | epic: true, 72 | loadout: 5, 73 | extended: true, 74 | image: 75 | 'https://infinitearenas.com/xw2/images/pilots/banditsquadronpilot.png', 76 | artwork: 77 | 'https://infinitearenas.com/xw2/images/artwork/pilots/banditsquadronpilot.png', 78 | }, 79 | { 80 | name: 'Lieutenant Blount', 81 | caption: 'Team Player', 82 | initiative: 4, 83 | limited: 1, 84 | cost: 3, 85 | xws: 'lieutenantblount', 86 | ability: 87 | 'While you perform a primary attack, if there is at least 1 other friendly ship at range 0-1 of the defender, you may roll 1 additional attack die.', 88 | slots: ['Talent', 'Talent', 'Modification'], 89 | ffg: 28, 90 | standard: true, 91 | epic: true, 92 | loadout: 11, 93 | extended: true, 94 | image: 95 | 'https://infinitearenas.com/xw2/images/pilots/lieutenantblount.png', 96 | artwork: 97 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lieutenantblount.png', 98 | }, 99 | { 100 | name: 'Tala Squadron Pilot', 101 | initiative: 2, 102 | limited: 0, 103 | cost: 3, 104 | xws: 'talasquadronpilot', 105 | text: 106 | 'The AF4 series is the latest in a long line of Headhunter designs. Cheap and relatively durable, it is a favorite among independent outfits like the Rebellion.', 107 | slots: ['Talent', 'Modification'], 108 | ffg: 29, 109 | standard: true, 110 | epic: true, 111 | loadout: 4, 112 | extended: true, 113 | image: 114 | 'https://infinitearenas.com/xw2/images/pilots/talasquadronpilot.png', 115 | artwork: 116 | 'https://infinitearenas.com/xw2/images/artwork/pilots/talasquadronpilot.png', 117 | }, 118 | ], 119 | }; 120 | 121 | export default t; 122 | -------------------------------------------------------------------------------- /src/assets/pilots/resistance/gr-75-medium-transport.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'GR-75 Medium Transport', 5 | xws: 'gr75mediumtransport', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BB', 12 | '1NB', 13 | '1FB', 14 | '2BW', 15 | '2NW', 16 | '2FW', 17 | '3FR', 18 | '4FR', 19 | ], 20 | faction: 'Resistance', 21 | stats: [], 22 | actions: [], 23 | ability: { 24 | name: 'Resupply Craft', 25 | text: 26 | 'After another friendly ship at range 0-1 performs an action, you may spend 1 [Energy]. If you do, it removes 1 orange or red token, or recovers 1 shield.', 27 | }, 28 | pilots: [ 29 | { 30 | name: 'New Republic Volunteers', 31 | text: 32 | 'In use since the Galactic Civil War, groups within the New Republic still utilize the GR-75 medium transport for supply and aid missions.', 33 | initiative: 7, 34 | engagement: 1, 35 | limited: 0, 36 | cost: 65, 37 | xws: 'newrepublicvolunteers', 38 | slots: [ 39 | 'Command', 40 | 'Hardpoint', 41 | 'Turret', 42 | 'Crew', 43 | 'Crew', 44 | 'Team', 45 | 'Cargo', 46 | 'Cargo', 47 | ], 48 | standard: false, 49 | extended: false, 50 | epic: true, 51 | ffg: 710, 52 | ability: 53 | 'In use since the Galactic Civil War, groups within the New Republic still utilize the GR-75 medium transport for supply and aid missions.', 54 | artwork: 55 | 'https://infinitearenas.com/xw2/images/artwork/pilots/newrepublicvolunteers.png', 56 | image: 57 | 'https://infinitearenas.com/xw2/images/pilots/newrepublicvolunteers.png', 58 | }, 59 | ], 60 | ffg: 80, 61 | icon: 62 | 'https://infinitearenas.com/xw2/images/shipicons/resistance/I_GR-75.png', 63 | }; 64 | 65 | export default t; 66 | -------------------------------------------------------------------------------- /src/assets/pilots/resistance/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import fireball from './fireball'; 3 | import gr75mediumtransport from './gr-75-medium-transport'; 4 | import mg100starfortress from './mg-100-starfortress'; 5 | import resistancetransport from './resistance-transport'; 6 | import resistancetransportpod from './resistance-transport-pod'; 7 | import rz2awing from './rz-2-a-wing'; 8 | import scavengedyt1300 from './scavenged-yt-1300'; 9 | import t70xwing from './t-70-x-wing'; 10 | import btanr2ywing from './bta-nr2-y-wing'; 11 | 12 | const ships: { [s: string]: ShipType } = { 13 | gr75mediumtransport, 14 | mg100starfortress, 15 | resistancetransportpod, 16 | resistancetransport, 17 | rz2awing, 18 | scavengedyt1300, 19 | t70xwing, 20 | fireball, 21 | btanr2ywing, 22 | }; 23 | 24 | export default ships; 25 | -------------------------------------------------------------------------------- /src/assets/pilots/resistance/resistance-transport-pod.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Resistance Transport Pod', 5 | xws: 'resistancetransportpod', 6 | size: 'Small', 7 | dial: [ 8 | '1TR', 9 | '1BB', 10 | '1FB', 11 | '1NB', 12 | '1YR', 13 | '2TW', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YW', 18 | '3BR', 19 | '3FW', 20 | '3NR', 21 | '3KR', 22 | '4FR', 23 | ], 24 | faction: 'Resistance', 25 | stats: [ 26 | { arc: 'Front Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 3 }, 29 | { type: 'shields', value: 1 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Lock' }, 34 | { difficulty: 'Red', type: 'Barrel Roll' }, 35 | { difficulty: 'Red', type: 'Jam' }, 36 | ], 37 | pilots: [ 38 | { 39 | name: 'BB-8', 40 | xws: 'bb8', 41 | initiative: 3, 42 | limited: 1, 43 | standard: true, 44 | epic: true, 45 | ability: 46 | 'During the System Phase, you may perform a red [Barrel Roll] or [Boost] action.', 47 | slots: ['Tech', 'Tech', 'Crew', 'Modification'], 48 | shipActions: [ 49 | { difficulty: 'White', type: 'Calculate' }, 50 | { difficulty: 'Red', type: 'Lock' }, 51 | { difficulty: 'Red', type: 'Barrel Roll' }, 52 | { difficulty: 'Red', type: 'Jam' }, 53 | ], 54 | cost: 2, 55 | ffg: 573, 56 | caption: 'Full of Surprises', 57 | keywords: ['Droid'], 58 | loadout: 4, 59 | extended: true, 60 | image: 'https://infinitearenas.com/xw2/images/pilots/bb8.png', 61 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/bb8.png', 62 | }, 63 | { 64 | name: 'Rose Tico', 65 | xws: 'rosetico', 66 | initiative: 3, 67 | limited: 1, 68 | caption: 'Earnest Engineer', 69 | standard: true, 70 | epic: true, 71 | ability: 72 | 'While you defend or perform an attack, you may reroll up to 1 of your results for each other friendly ship in the attack arc.', 73 | slots: ['Talent', 'Tech', 'Crew', 'Modification', 'Modification'], 74 | cost: 3, 75 | ffg: 574, 76 | loadout: 9, 77 | extended: true, 78 | image: 'https://infinitearenas.com/xw2/images/pilots/rosetico.png', 79 | artwork: 80 | 'https://infinitearenas.com/xw2/images/artwork/pilots/rosetico.png', 81 | }, 82 | { 83 | name: 'Vi Moradi', 84 | xws: 'vimoradi', 85 | initiative: 1, 86 | limited: 1, 87 | caption: 'Starling', 88 | standard: false, 89 | epic: true, 90 | ability: 91 | 'Setup: After placing forces, assign the Compromising Intel condition to 1 enemy ship.', 92 | conditions: ['compromisingintel'], 93 | slots: ['Tech', 'Crew', 'Modification'], 94 | cost: 3, 95 | ffg: 576, 96 | loadout: 6, 97 | extended: true, 98 | image: 'https://infinitearenas.com/xw2/images/pilots/vimoradi.png', 99 | artwork: 100 | 'https://infinitearenas.com/xw2/images/artwork/pilots/vimoradi.png', 101 | }, 102 | { 103 | name: 'Finn', 104 | xws: 'finn', 105 | initiative: 2, 106 | limited: 1, 107 | standard: true, 108 | epic: true, 109 | ability: 110 | 'While you defend or perform an attack, you may add 1 blank result, or you may gain 1 strain token to add 1 focus result instead.', 111 | slots: ['Talent', 'Talent', 'Tech', 'Crew', 'Modification'], 112 | cost: 4, 113 | ffg: 575, 114 | caption: 'Big Deal', 115 | loadout: 15, 116 | extended: true, 117 | image: 'https://infinitearenas.com/xw2/images/pilots/finn.png', 118 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/finn.png', 119 | }, 120 | ], 121 | ffg: 65, 122 | icon: 123 | 'https://infinitearenas.com/xw2/images/shipicons/resistance/I_Resistance_Transport_Cockpit_Pod.png', 124 | }; 125 | 126 | export default t; 127 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/c-roc-cruiser.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'C-ROC Cruiser', 5 | xws: 'croccruiser', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FB', 14 | '2BW', 15 | '2NW', 16 | '2FB', 17 | '3NR', 18 | '3FW', 19 | '3BR', 20 | '4FR', 21 | '5FR', 22 | ], 23 | faction: 'Scum and Villainy', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { type: 'agility', value: 0 }, 27 | { type: 'hull', value: 12 }, 28 | { type: 'shields', value: 4, recovers: 1 }, 29 | { type: 'energy', value: 4, recovers: 1 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'White', type: 'Lock' }, 34 | { difficulty: 'White', type: 'Reinforce' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | { difficulty: 'White', type: 'Jam' }, 37 | ], 38 | ability: { 39 | name: 'Overdrive Burners', 40 | text: 41 | 'While you defend, if your revealed maneuver is speed 3-5, roll 1 additional defense die.', 42 | }, 43 | pilots: [ 44 | { 45 | name: 'Syndicate Smugglers', 46 | text: 47 | 'Vessels like the C-ROC Cruiser allow criminal operations across the Outer Rim to move massive amounts of illicit materials, or project power that can bully small colonies into compliance.', 48 | initiative: 7, 49 | engagement: 1, 50 | limited: 0, 51 | cost: 63, 52 | xws: 'syndicatesmugglers', 53 | slots: [ 54 | 'Command', 55 | 'Hardpoint', 56 | 'Crew', 57 | 'Crew', 58 | 'Team', 59 | 'Cargo', 60 | 'Device', 61 | 'Illicit', 62 | 'Title', 63 | 'Configuration', 64 | ], 65 | standard: false, 66 | extended: false, 67 | epic: true, 68 | ffg: 713, 69 | artwork: 70 | 'https://infinitearenas.com/xw2/images/artwork/pilots/syndicatesmugglers.png', 71 | image: 72 | 'https://infinitearenas.com/xw2/images/pilots/syndicatesmugglers.png', 73 | }, 74 | ], 75 | ffg: 82, 76 | icon: 77 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_C-ROC.png', 78 | }; 79 | 80 | export default t; 81 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/escape-craft.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Escape Craft', 5 | xws: 'escapecraft', 6 | ffg: 85, 7 | size: 'Small', 8 | dial: [ 9 | '0OR', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '2TR', 14 | '2BW', 15 | '2FB', 16 | '2NW', 17 | '2YR', 18 | '3BW', 19 | '3FW', 20 | '3NW', 21 | '3KR', 22 | ], 23 | faction: 'Scum and Villainy', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 2 }, 26 | { type: 'agility', value: 2 }, 27 | { type: 'hull', value: 2 }, 28 | { type: 'shields', value: 2 }, 29 | ], 30 | actions: [ 31 | { difficulty: 'White', type: 'Focus' }, 32 | { difficulty: 'White', type: 'Barrel Roll' }, 33 | { difficulty: 'Red', type: 'Coordinate' }, 34 | ], 35 | ability: { 36 | name: 'Copilot', 37 | text: 38 | 'While you are docked, your carrier ship has your pilot ability in addition to its own.', 39 | }, 40 | icon: 41 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_EscapeShuttle.png', 42 | pilots: [ 43 | { 44 | name: 'Autopilot Drone', 45 | caption: 'Set to Blow', 46 | initiative: 1, 47 | limited: 1, 48 | cost: 2, 49 | xws: 'autopilotdrone', 50 | text: "Sometimes, manufacturer's warnings are made to be broken.", 51 | charges: { value: 3, recovers: 0 }, 52 | shipActions: [ 53 | { difficulty: 'White', type: 'Calculate' }, 54 | { difficulty: 'White', type: 'Barrel Roll' }, 55 | { difficulty: 'Red', type: 'Coordinate' }, 56 | ], 57 | shipAbility: { 58 | name: 'Rigged Energy Cells', 59 | text: 60 | 'During the System Phase, if you are not docked, lose 1 [Charge]. At the end of the Activation Phase, if you have 0 [Charge], you are destroyed. Before you are removed, each ship at range 0-1 suffers 1 [Critical Hit] damage.', 61 | }, 62 | slots: [], 63 | ffg: 229, 64 | standard: true, 65 | epic: true, 66 | loadout: 0, 67 | extended: true, 68 | image: 'https://infinitearenas.com/xw2/images/pilots/autopilotdrone.png', 69 | artwork: 70 | 'https://infinitearenas.com/xw2/images/artwork/pilots/autopilotdrone.png', 71 | }, 72 | { 73 | name: 'L3-37', 74 | caption: 'Droid Revolutionary', 75 | initiative: 2, 76 | limited: 1, 77 | cost: 3, 78 | xws: 'l337-escapecraft', 79 | ability: 80 | 'If you are not shielded, decrease the difficulty of your bank ([Bank Left] and [Bank Right]) maneuvers.', 81 | shipActions: [ 82 | { difficulty: 'White', type: 'Calculate' }, 83 | { difficulty: 'White', type: 'Barrel Roll' }, 84 | { difficulty: 'Red', type: 'Coordinate' }, 85 | ], 86 | slots: ['Talent', 'Crew', 'Modification'], 87 | ffg: 228, 88 | standard: true, 89 | epic: true, 90 | keywords: ['Droid'], 91 | loadout: 4, 92 | extended: true, 93 | image: 94 | 'https://infinitearenas.com/xw2/images/pilots/l337-escapecraft.png', 95 | artwork: 96 | 'https://infinitearenas.com/xw2/images/artwork/pilots/l337-escapecraft.png', 97 | }, 98 | { 99 | name: 'Lando Calrissian', 100 | caption: 'Smooth-talking Gambler', 101 | initiative: 4, 102 | limited: 1, 103 | cost: 3, 104 | xws: 'landocalrissian-escapecraft', 105 | ability: 106 | 'After you roll dice, if you are not stressed, you may gain 1 stress token to reroll all of your blank results.', 107 | slots: ['Talent', 'Crew', 'Modification'], 108 | ffg: 226, 109 | standard: true, 110 | epic: true, 111 | loadout: 4, 112 | extended: true, 113 | image: 114 | 'https://infinitearenas.com/xw2/images/pilots/landocalrissian-escapecraft.png', 115 | artwork: 116 | 'https://infinitearenas.com/xw2/images/artwork/pilots/landocalrissian-escapecraft.png', 117 | }, 118 | { 119 | name: 'Outer Rim Pioneer', 120 | caption: 'Skillful Outlaw', 121 | initiative: 3, 122 | limited: 1, 123 | cost: 3, 124 | xws: 'outerrimpioneer', 125 | ability: 126 | 'Friendly ships at range 0-1 can perform attacks at range 0 of obstacles.', 127 | slots: ['Talent', 'Crew', 'Modification'], 128 | ffg: 227, 129 | standard: true, 130 | epic: true, 131 | loadout: 4, 132 | extended: true, 133 | image: 'https://infinitearenas.com/xw2/images/pilots/outerrimpioneer.png', 134 | artwork: 135 | 'https://infinitearenas.com/xw2/images/artwork/pilots/outerrimpioneer.png', 136 | }, 137 | ], 138 | }; 139 | 140 | export default t; 141 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/g-1a-starfighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'G-1A Starfighter', 5 | xws: 'g1astarfighter', 6 | ffg: 22, 7 | size: 'Medium', 8 | dial: [ 9 | '0OR', 10 | '1TR', 11 | '1BB', 12 | '1FB', 13 | '1NB', 14 | '1YR', 15 | '2TW', 16 | '2BW', 17 | '2FB', 18 | '2NW', 19 | '2YW', 20 | '2KR', 21 | '3BR', 22 | '3FW', 23 | '3NR', 24 | '4FR', 25 | '4KR', 26 | ], 27 | faction: 'Scum and Villainy', 28 | stats: [ 29 | { arc: 'Front Arc', type: 'attack', value: 3 }, 30 | { type: 'agility', value: 1 }, 31 | { type: 'hull', value: 5 }, 32 | { type: 'shields', value: 4 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'White', type: 'Lock' }, 37 | { difficulty: 'White', type: 'Jam' }, 38 | ], 39 | icon: 40 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_MistHunter.png', 41 | pilots: [ 42 | { 43 | name: '4-LOM', 44 | caption: 'Reprogrammed Protocol Droid', 45 | initiative: 3, 46 | limited: 1, 47 | cost: 5, 48 | xws: '4lom', 49 | ability: 50 | 'After you fully execute a red maneuver, gain 1 calculate token. At the start of the End Phase, you may choose 1 ship at range 0-1. If you do, transfer 1 of your stress tokens to that ship.', 51 | slots: ['Talent', 'Sensor', 'Crew', 'Illicit', 'Modification', 'Title'], 52 | shipActions: [ 53 | { difficulty: 'White', type: 'Calculate' }, 54 | { difficulty: 'White', type: 'Lock' }, 55 | { difficulty: 'White', type: 'Jam' }, 56 | ], 57 | ffg: 201, 58 | standard: false, 59 | epic: true, 60 | keywords: ['Bounty Hunter', 'Droid'], 61 | loadout: 14, 62 | extended: true, 63 | image: 'https://infinitearenas.com/xw2/images/pilots/4lom.png', 64 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/4lom.png', 65 | }, 66 | { 67 | name: 'Gand Findsman', 68 | initiative: 1, 69 | limited: 0, 70 | cost: 5, 71 | xws: 'gandfindsman', 72 | text: 73 | 'The legendary Findsmen of Gand worship the enshrouding mists of their home planet, using signs, augurs, and mystical rituals to track their quarry.', 74 | slots: ['Illicit'], 75 | ffg: 203, 76 | standard: false, 77 | epic: true, 78 | loadout: 3, 79 | extended: true, 80 | keywords: ['Bounty Hunter'], 81 | image: 'https://infinitearenas.com/xw2/images/pilots/gandfindsman.png', 82 | artwork: 83 | 'https://infinitearenas.com/xw2/images/artwork/pilots/gandfindsman.png', 84 | }, 85 | { 86 | name: 'Zuckuss', 87 | caption: 'Meditative Gand', 88 | initiative: 3, 89 | limited: 1, 90 | cost: 5, 91 | xws: 'zuckuss', 92 | ability: 93 | 'While you perform a primary attack, you may roll 1 additional attack die. If you do, the defender rolls 1 additional defense die.', 94 | slots: ['Talent', 'Sensor', 'Crew', 'Illicit', 'Modification', 'Title'], 95 | ffg: 202, 96 | standard: false, 97 | epic: true, 98 | loadout: 10, 99 | extended: true, 100 | keywords: ['Bounty Hunter'], 101 | image: 'https://infinitearenas.com/xw2/images/pilots/zuckuss.png', 102 | artwork: 103 | 'https://infinitearenas.com/xw2/images/artwork/pilots/zuckuss.png', 104 | }, 105 | ], 106 | }; 107 | 108 | export default t; 109 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/gauntlet-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gauntlet Fighter', 5 | xws: 'gauntletfighter', 6 | size: 'Large', 7 | dial: [ 8 | '0OR', 9 | '1BB', 10 | '1NB', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TR', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | '3YR', 21 | '4FW', 22 | ], 23 | faction: 'Scum and Villainy', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 9 }, 29 | { type: 'shields', value: 2 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Reinforce' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | ], 37 | pilots: [ 38 | { 39 | xws: 'maul', 40 | name: 'Maul', 41 | ability: 42 | 'While you perform a [Coordinate] action, if you choose a ship with an initiative lower than yours, you may spend 1 [Force]. If you do, treat the action as white and you may coordinate 1 additional friendly ship with an initiative lower than yours; each friendly ship you coordinate this way gains 1 strain token.', 43 | force: { side: ['dark'], value: 3, recovers: 1 }, 44 | cost: 8, 45 | loadout: 15, 46 | initiative: 5, 47 | limited: 1, 48 | standard: true, 49 | extended: true, 50 | epic: true, 51 | slots: [ 52 | 'Force Power', 53 | 'Talent', 54 | 'Crew', 55 | 'Gunner', 56 | 'Device', 57 | 'Illicit', 58 | 'Modification', 59 | 'Modification', 60 | 'Configuration', 61 | 'Title', 62 | ], 63 | keywords: ['Dark Side'], 64 | caption: 'Lord of the Shadow Collective', 65 | image: 'https://infinitearenas.com/xw2/images/pilots/maul.png', 66 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/maul.png', 67 | }, 68 | { 69 | xws: 'rookkast', 70 | name: 'Rook Kast', 71 | cost: 7, 72 | loadout: 14, 73 | initiative: 3, 74 | limited: 1, 75 | ability: 76 | 'Before you engage, you may gain 1 strain token. While you perform a primary attack, if you are strained, you may change 1 of your blank or [Focus] results to a [Hit] result.', 77 | standard: true, 78 | extended: true, 79 | epic: true, 80 | slots: [ 81 | 'Talent', 82 | 'Crew', 83 | 'Gunner', 84 | 'Device', 85 | 'Illicit', 86 | 'Modification', 87 | 'Configuration', 88 | ], 89 | keywords: ['Mandalorian'], 90 | caption: 'Stoic Super Commando', 91 | image: 'https://infinitearenas.com/xw2/images/pilots/rookkast.png', 92 | artwork: 93 | 'https://infinitearenas.com/xw2/images/artwork/pilots/rookkast.png', 94 | }, 95 | { 96 | xws: 'shadowcollectiveoperator', 97 | name: 'Shadow Collective Operator', 98 | cost: 7, 99 | loadout: 10, 100 | initiative: 1, 101 | limited: 0, 102 | standard: true, 103 | extended: true, 104 | epic: true, 105 | slots: [ 106 | 'Crew', 107 | 'Gunner', 108 | 'Device', 109 | 'Device', 110 | 'Illicit', 111 | 'Modification', 112 | 'Configuration', 113 | ], 114 | keywords: ['Mandalorian'], 115 | image: 116 | 'https://infinitearenas.com/xw2/images/pilots/shadowcollectiveoperator.png', 117 | artwork: 118 | 'https://infinitearenas.com/xw2/images/artwork/pilots/shadowcollectiveoperator.png', 119 | }, 120 | ], 121 | }; 122 | 123 | export default t; 124 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import aggressorassaultfighter from './aggressor-assault-fighter'; 3 | import btla4ywing from './btl-a4-y-wing'; 4 | import croccruiser from './c-roc-cruiser'; 5 | import customizedyt1300lightfreighter from './customized-yt-1300-light-freighter'; 6 | import escapecraft from './escape-craft'; 7 | import fangfighter from './fang-fighter'; 8 | import firesprayclasspatrolcraft from './firespray-class-patrol-craft'; 9 | import g1astarfighter from './g-1a-starfighter'; 10 | import hwk290lightfreighter from './hwk-290-light-freighter'; 11 | import jumpmaster5000 from './jumpmaster-5000'; 12 | import kihraxzfighter from './kihraxz-fighter'; 13 | import lancerclasspursuitcraft from './lancer-class-pursuit-craft'; 14 | import m12lkimogilafighter from './m12-l-kimogila-fighter'; 15 | import m3ainterceptor from './m3-a-interceptor'; 16 | import modifiedtielnfighter from './modified-tie-ln-fighter'; 17 | import quadrijettransferspacetug from './quadrijet-transfer-spacetug'; 18 | import scurrgh6bomber from './scurrg-h-6-bomber'; 19 | import starviperclassattackplatform from './starviper-class-attack-platform'; 20 | import yv666lightfreighter from './yv-666-light-freighter'; 21 | import z95af4headhunter from './z-95-af4-headhunter'; 22 | import tridentclassassaultship from './trident-class-assault-ship'; 23 | import gauntletfighter from './gauntlet-fighter'; 24 | import st70assaultship from './st-70-assault-ship'; 25 | import rogueclassstarfighter from './rogue-class-starfighter'; 26 | import yt2400lightfreighter from './yt-2400-light-freighter'; 27 | 28 | const ships: { [s: string]: ShipType } = { 29 | aggressorassaultfighter, 30 | btla4ywing, 31 | customizedyt1300lightfreighter, 32 | croccruiser, 33 | escapecraft, 34 | fangfighter, 35 | firesprayclasspatrolcraft, 36 | gauntletfighter, 37 | g1astarfighter, 38 | hwk290lightfreighter, 39 | jumpmaster5000, 40 | kihraxzfighter, 41 | lancerclasspursuitcraft, 42 | m12lkimogilafighter, 43 | m3ainterceptor, 44 | modifiedtielnfighter, 45 | quadrijettransferspacetug, 46 | scurrgh6bomber, 47 | starviperclassattackplatform, 48 | st70assaultship, 49 | yv666lightfreighter, 50 | z95af4headhunter, 51 | tridentclassassaultship, 52 | rogueclassstarfighter, 53 | yt2400lightfreighter, 54 | }; 55 | 56 | export default ships; 57 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/lancer-class-pursuit-craft.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Lancer-class Pursuit Craft', 5 | xws: 'lancerclasspursuitcraft', 6 | ffg: 42, 7 | size: 'Large', 8 | dial: [ 9 | '1BW', 10 | '1FW', 11 | '1NW', 12 | '2TW', 13 | '2BW', 14 | '2FB', 15 | '2NW', 16 | '2YW', 17 | '3TB', 18 | '3BB', 19 | '3FB', 20 | '3NB', 21 | '3YB', 22 | '4FB', 23 | '5FW', 24 | '5KR', 25 | ], 26 | faction: 'Scum and Villainy', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 3 }, 29 | { arc: 'Single Turret Arc', type: 'attack', value: 2 }, 30 | { type: 'agility', value: 2 }, 31 | { type: 'hull', value: 8 }, 32 | { type: 'shields', value: 2 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'White', type: 'Evade' }, 37 | { difficulty: 'White', type: 'Lock' }, 38 | { difficulty: 'White', type: 'Rotate Arc' }, 39 | ], 40 | icon: 41 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_ShadowCaster.png', 42 | pilots: [ 43 | { 44 | name: 'Asajj Ventress', 45 | caption: 'Force of Her Own', 46 | initiative: 4, 47 | limited: 1, 48 | cost: 8, 49 | xws: 'asajjventress', 50 | ability: 51 | 'At the start of the Engagement Phase, you may choose 1 enemy ship in your [Single Turret Arc] at range 0-2 and spend 1 [Force]. If you do, that ship gains 1 stress token unless it removes 1 green token.', 52 | force: { value: 2, recovers: 1, side: ['dark'] }, 53 | slots: [ 54 | 'Force Power', 55 | 'Talent', 56 | 'Crew', 57 | 'Illicit', 58 | 'Illicit', 59 | 'Modification', 60 | ], 61 | ffg: 219, 62 | standard: false, 63 | epic: true, 64 | loadout: 20, 65 | extended: true, 66 | keywords: ['Bounty Hunter', 'Dark Side'], 67 | image: 'https://infinitearenas.com/xw2/images/pilots/asajjventress.png', 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/asajjventress.png', 70 | }, 71 | { 72 | name: 'Ketsu Onyo', 73 | caption: 'Black Sun Contractor', 74 | initiative: 5, 75 | limited: 1, 76 | cost: 7, 77 | xws: 'ketsuonyo', 78 | ability: 79 | 'At the start of the Engagement Phase, you may choose 1 ship in both your [Front Arc] and [Single Turret Arc] at range 0-1. If you do, that ship gains 1 tractor token.', 80 | slots: ['Talent', 'Crew', 'Illicit', 'Illicit', 'Modification', 'Title'], 81 | ffg: 218, 82 | standard: false, 83 | epic: true, 84 | loadout: 15, 85 | extended: true, 86 | keywords: ['Bounty Hunter', 'Mandalorian'], 87 | image: 'https://infinitearenas.com/xw2/images/pilots/ketsuonyo.png', 88 | artwork: 89 | 'https://infinitearenas.com/xw2/images/artwork/pilots/ketsuonyo.png', 90 | }, 91 | { 92 | name: 'Sabine Wren', 93 | caption: 'Artistic Saboteur', 94 | initiative: 3, 95 | limited: 1, 96 | cost: 6, 97 | xws: 'sabinewren-lancerclasspursuitcraft', 98 | ability: 99 | 'While you defend, if the attacker is in your [Single Turret Arc] at range 0-2, you may add 1 [Focus] result to your dice results.', 100 | slots: ['Talent', 'Crew', 'Illicit', 'Illicit', 'Modification', 'Title'], 101 | ffg: 220, 102 | standard: false, 103 | epic: true, 104 | loadout: 9, 105 | extended: true, 106 | keywords: ['Bounty Hunter', 'Mandalorian'], 107 | image: 108 | 'https://infinitearenas.com/xw2/images/pilots/sabinewren-lancerclasspursuitcraft.png', 109 | artwork: 110 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sabinewren-lancerclasspursuitcraft.png', 111 | }, 112 | { 113 | name: 'Shadowport Hunter', 114 | initiative: 2, 115 | limited: 0, 116 | cost: 6, 117 | xws: 'shadowporthunter', 118 | text: 119 | 'Crime syndicates augment the lethal skills of their loyal contractors with the best technology available, like the fast and formidable Lancer-class pursuit craft.', 120 | slots: ['Illicit', 'Illicit'], 121 | ffg: 221, 122 | standard: false, 123 | epic: true, 124 | keywords: ['Bounty Hunter'], 125 | loadout: 6, 126 | extended: true, 127 | image: 128 | 'https://infinitearenas.com/xw2/images/pilots/shadowporthunter.png', 129 | artwork: 130 | 'https://infinitearenas.com/xw2/images/artwork/pilots/shadowporthunter.png', 131 | }, 132 | ], 133 | }; 134 | 135 | export default t; 136 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/m12-l-kimogila-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'M12-L Kimogila Fighter', 5 | xws: 'm12lkimogilafighter', 6 | ffg: 39, 7 | size: 'Medium', 8 | dial: [ 9 | '1TR', 10 | '1BW', 11 | '1FB', 12 | '1NW', 13 | '1YR', 14 | '2TW', 15 | '2BB', 16 | '2FB', 17 | '2NB', 18 | '2YW', 19 | '3TW', 20 | '3BW', 21 | '3FB', 22 | '3NW', 23 | '3YW', 24 | '4KR', 25 | ], 26 | faction: 'Scum and Villainy', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 3 }, 29 | { type: 'agility', value: 1 }, 30 | { type: 'hull', value: 7 }, 31 | { type: 'shields', value: 2 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { difficulty: 'Red', type: 'Barrel Roll' }, 37 | { difficulty: 'White', type: 'Reload' }, 38 | ], 39 | ability: { 40 | name: 'Dead to Rights', 41 | text: 42 | 'While you perform an attack, if the defender is in your [Bullseye Arc], defense dice cannot be modified using green tokens.', 43 | }, 44 | icon: 45 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_Kimogila.png', 46 | pilots: [ 47 | { 48 | name: 'Cartel Executioner', 49 | initiative: 3, 50 | limited: 0, 51 | cost: 5, 52 | xws: 'cartelexecutioner', 53 | text: 54 | 'Many veteran pilots in the service of the Hutt kajidics and other criminal operations choose the M12-L Kimogila for its firepower and dreaded reputation alike.', 55 | slots: ['Missile'], 56 | ffg: 209, 57 | standard: false, 58 | epic: true, 59 | loadout: 3, 60 | extended: true, 61 | image: 62 | 'https://infinitearenas.com/xw2/images/pilots/cartelexecutioner.png', 63 | artwork: 64 | 'https://infinitearenas.com/xw2/images/artwork/pilots/cartelexecutioner.png', 65 | }, 66 | { 67 | name: 'Dalan Oberos', 68 | caption: 'Returned from the Grave', 69 | initiative: 3, 70 | limited: 1, 71 | cost: 5, 72 | xws: 'dalanoberos', 73 | ability: 74 | 'At the start of the Engagement Phase, you may choose 1 shielded ship in your [Bullseye Arc] and spend 1 [Charge]. If you do, that ship loses 1 shield and you recover 1 shield.', 75 | charges: { value: 2, recovers: 0 }, 76 | slots: [ 77 | 'Talent', 78 | 'Torpedo', 79 | 'Missile', 80 | 'Astromech', 81 | 'Illicit', 82 | 'Modification', 83 | ], 84 | ffg: 208, 85 | standard: false, 86 | epic: true, 87 | loadout: 12, 88 | extended: true, 89 | keywords: ['Bounty Hunter'], 90 | image: 'https://infinitearenas.com/xw2/images/pilots/dalanoberos.png', 91 | artwork: 92 | 'https://infinitearenas.com/xw2/images/artwork/pilots/dalanoberos.png', 93 | }, 94 | { 95 | name: 'Torani Kulda', 96 | caption: 'Rodian Freelancer', 97 | initiative: 4, 98 | limited: 1, 99 | cost: 5, 100 | xws: 'toranikulda', 101 | ability: 102 | 'After you perform an attack, each enemy ship in your [Bullseye Arc] suffers 1 [Hit] damage unless it removes 1 green token.', 103 | slots: [ 104 | 'Talent', 105 | 'Torpedo', 106 | 'Missile', 107 | 'Astromech', 108 | 'Illicit', 109 | 'Modification', 110 | ], 111 | ffg: 207, 112 | standard: false, 113 | epic: true, 114 | loadout: 10, 115 | extended: true, 116 | keywords: ['Bounty Hunter'], 117 | image: 'https://infinitearenas.com/xw2/images/pilots/toranikulda.png', 118 | artwork: 119 | 'https://infinitearenas.com/xw2/images/artwork/pilots/toranikulda.png', 120 | }, 121 | ], 122 | }; 123 | 124 | export default t; 125 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/quadrijet-transfer-spacetug.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Quadrijet Transfer Spacetug', 5 | xws: 'quadrijettransferspacetug', 6 | ffg: 9, 7 | size: 'Small', 8 | dial: [ 9 | '1AR', 10 | '1DR', 11 | '1TW', 12 | '1BW', 13 | '1FW', 14 | '1NW', 15 | '1YW', 16 | '2SR', 17 | '2LR', 18 | '2TW', 19 | '2BB', 20 | '2FB', 21 | '2NB', 22 | '2YW', 23 | '2PR', 24 | '3BW', 25 | '3FB', 26 | '3NW', 27 | ], 28 | faction: 'Scum and Villainy', 29 | stats: [ 30 | { arc: 'Front Arc', type: 'attack', value: 2 }, 31 | { type: 'agility', value: 2 }, 32 | { type: 'hull', value: 5 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'Red', type: 'Evade' }, 37 | { difficulty: 'White', type: 'Barrel Roll' }, 38 | ], 39 | ability: { 40 | name: 'Spacetug Tractor Array', 41 | text: 42 | 'Action: Choose a ship in your [Front Arc] at range 1. That ship gains 1 tractor token, or 2 tractor tokens if it is in your [Bullseye Arc] at range 1.', 43 | }, 44 | icon: 45 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_Quadjumper.png', 46 | pilots: [ 47 | { 48 | name: 'Constable Zuvio', 49 | caption: 'Missing Sheriff of Niima Outpost', 50 | initiative: 4, 51 | limited: 1, 52 | cost: 4, 53 | xws: 'constablezuvio', 54 | ability: 55 | 'If you would drop a device, you may launch it using a (1 [Straight]) template instead.', 56 | slots: ['Talent', 'Tech', 'Device', 'Device', 'Illicit', 'Modification'], 57 | ffg: 161, 58 | standard: false, 59 | epic: true, 60 | loadout: 13, 61 | extended: true, 62 | image: 'https://infinitearenas.com/xw2/images/pilots/constablezuvio.png', 63 | artwork: 64 | 'https://infinitearenas.com/xw2/images/artwork/pilots/constablezuvio.png', 65 | }, 66 | { 67 | name: 'Jakku Gunrunner', 68 | initiative: 1, 69 | limited: 0, 70 | cost: 4, 71 | xws: 'jakkugunrunner', 72 | text: 73 | 'The Quadrijet transfer spacetug, commonly called a "Quadjumper," is nimble in space and atmosphere alike, making it popular among both smugglers and explorers.', 74 | slots: ['Device', 'Illicit'], 75 | ffg: 164, 76 | standard: false, 77 | epic: true, 78 | loadout: 4, 79 | extended: true, 80 | image: 'https://infinitearenas.com/xw2/images/pilots/jakkugunrunner.png', 81 | artwork: 82 | 'https://infinitearenas.com/xw2/images/artwork/pilots/jakkugunrunner.png', 83 | }, 84 | { 85 | name: 'Sarco Plank', 86 | caption: 'The Scavenger', 87 | initiative: 2, 88 | limited: 1, 89 | cost: 4, 90 | xws: 'sarcoplank', 91 | ability: 92 | 'While you defend, you may treat your agility value as equal to the speed of the maneuver you executed this round.', 93 | slots: ['Tech', 'Crew', 'Device', 'Illicit', 'Illicit', 'Modification'], 94 | ffg: 162, 95 | standard: false, 96 | epic: true, 97 | loadout: 6, 98 | extended: true, 99 | keywords: ['Bounty Hunter'], 100 | image: 'https://infinitearenas.com/xw2/images/pilots/sarcoplank.png', 101 | artwork: 102 | 'https://infinitearenas.com/xw2/images/artwork/pilots/sarcoplank.png', 103 | }, 104 | { 105 | name: 'Unkar Plutt', 106 | caption: 'Miserly Portion Master', 107 | initiative: 2, 108 | limited: 1, 109 | cost: 4, 110 | xws: 'unkarplutt', 111 | ability: 112 | 'At the start of the Engagement Phase, if there are one or more other ships at range 0, you and each other ship at range 0 gain 1 tractor token.', 113 | slots: ['Tech', 'Crew', 'Device', 'Illicit', 'Modification'], 114 | ffg: 163, 115 | standard: false, 116 | epic: true, 117 | loadout: 7, 118 | extended: true, 119 | image: 'https://infinitearenas.com/xw2/images/pilots/unkarplutt.png', 120 | artwork: 121 | 'https://infinitearenas.com/xw2/images/artwork/pilots/unkarplutt.png', 122 | }, 123 | ], 124 | }; 125 | 126 | export default t; 127 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/scurrg-h-6-bomber.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Scurrg H-6 bomber', 5 | xws: 'scurrgh6bomber', 6 | ffg: 4, 7 | size: 'Medium', 8 | dial: [ 9 | '1BB', 10 | '1FB', 11 | '1NB', 12 | '2TW', 13 | '2BW', 14 | '2FB', 15 | '2NW', 16 | '2YW', 17 | '3ER', 18 | '3TR', 19 | '3BW', 20 | '3FW', 21 | '3NW', 22 | '3YR', 23 | '3RR', 24 | '4FR', 25 | ], 26 | faction: 'Scum and Villainy', 27 | stats: [ 28 | { arc: 'Front Arc', type: 'attack', value: 3 }, 29 | { type: 'agility', value: 1 }, 30 | { type: 'hull', value: 6 }, 31 | { type: 'shields', value: 4 }, 32 | ], 33 | actions: [ 34 | { difficulty: 'White', type: 'Focus' }, 35 | { difficulty: 'White', type: 'Lock' }, 36 | { difficulty: 'Red', type: 'Barrel Roll' }, 37 | ], 38 | icon: 39 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_Scurrg.png', 40 | pilots: [ 41 | { 42 | name: 'Captain Nym', 43 | caption: 'Captain of the Lok Revenants', 44 | initiative: 5, 45 | limited: 1, 46 | cost: 6, 47 | xws: 'captainnym', 48 | ability: 49 | 'Before a friendly bomb or mine would detonate, you may spend 1 [Charge] to prevent it from detonating. While you defend against an attack obstructed by a bomb or mine, roll 1 additional defense die.', 50 | charges: { value: 1, recovers: 1 }, 51 | slots: [ 52 | 'Talent', 53 | 'Turret', 54 | 'Crew', 55 | 'Gunner', 56 | 'Device', 57 | 'Device', 58 | 'Modification', 59 | 'Title', 60 | ], 61 | ffg: 204, 62 | standard: false, 63 | epic: true, 64 | loadout: 17, 65 | extended: true, 66 | image: 'https://infinitearenas.com/xw2/images/pilots/captainnym.png', 67 | artwork: 68 | 'https://infinitearenas.com/xw2/images/artwork/pilots/captainnym.png', 69 | }, 70 | { 71 | name: 'Lok Revenant', 72 | initiative: 2, 73 | limited: 0, 74 | cost: 5, 75 | xws: 'lokrevenant', 76 | text: 77 | 'The Nubian Design Collective crafted the Scurrg H-6 Bomber with combat versatility in mind, arming it with powerful shields and a bristling array of destructive weaponry.', 78 | slots: ['Turret', 'Gunner', 'Device', 'Device'], 79 | ffg: 206, 80 | standard: false, 81 | epic: true, 82 | loadout: 8, 83 | extended: true, 84 | image: 'https://infinitearenas.com/xw2/images/pilots/lokrevenant.png', 85 | artwork: 86 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lokrevenant.png', 87 | }, 88 | { 89 | name: 'Sol Sixxa', 90 | caption: 'Cunning Commander', 91 | initiative: 3, 92 | limited: 1, 93 | cost: 5, 94 | xws: 'solsixxa', 95 | ability: 96 | 'If you would drop a device using a (1 [Straight]) template, you may drop it using any other speed 1 template instead.', 97 | slots: [ 98 | 'Talent', 99 | 'Turret', 100 | 'Crew', 101 | 'Gunner', 102 | 'Device', 103 | 'Device', 104 | 'Modification', 105 | ], 106 | ffg: 205, 107 | standard: false, 108 | epic: true, 109 | loadout: 12, 110 | extended: true, 111 | image: 'https://infinitearenas.com/xw2/images/pilots/solsixxa.png', 112 | artwork: 113 | 'https://infinitearenas.com/xw2/images/artwork/pilots/solsixxa.png', 114 | }, 115 | ], 116 | }; 117 | 118 | export default t; 119 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/st-70-assault-ship.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'ST-70 Assault Ship', 5 | xws: 'st70assaultship', 6 | size: 'Medium', 7 | dial: [ 8 | '0OR', 9 | '1TR', 10 | '1BW', 11 | '1FB', 12 | '1NW', 13 | '1YR', 14 | '2TW', 15 | '2ER', 16 | '2BW', 17 | '2FB', 18 | '2NW', 19 | '2YW', 20 | '2RR', 21 | '3TR', 22 | '3BW', 23 | '3FB', 24 | '3NW', 25 | '3YR', 26 | '4FB', 27 | '5KR', 28 | ], 29 | faction: 'Scum and Villainy', 30 | stats: [ 31 | { arc: 'Front Arc', type: 'attack', value: 3 }, 32 | { type: 'agility', value: 2 }, 33 | { type: 'hull', value: 7 }, 34 | { type: 'shields', value: 2 }, 35 | ], 36 | actions: [ 37 | { difficulty: 'White', type: 'Focus' }, 38 | { difficulty: 'White', type: 'Evade' }, 39 | { difficulty: 'White', type: 'Lock' }, 40 | { difficulty: 'Red', type: 'Barrel Roll' }, 41 | ], 42 | pilots: [ 43 | { 44 | xws: 'themandalorian', 45 | name: 'The Mandalorian', 46 | caption: 'Din Djarin', 47 | initiative: 5, 48 | limited: 1, 49 | cost: 6, 50 | loadout: 10, 51 | ability: 52 | 'While you defend or perform an attack, if you are in the [Front Arc] at range 1-2 of 2 or more enemy ships, you may change 1 of you blank results to a [Focus] result.', 53 | slots: [ 54 | 'Talent', 55 | 'Crew', 56 | 'Gunner', 57 | 'Illicit', 58 | 'Illicit', 59 | 'Modification', 60 | 'Title', 61 | ], 62 | standard: true, 63 | epic: true, 64 | extended: true, 65 | keywords: ['Mandalorian', 'Bounty Hunter'], 66 | image: 'https://infinitearenas.com/xw2/images/pilots/themandalorian.png', 67 | artwork: 68 | 'https://infinitearenas.com/xw2/images/artwork/pilots/themandalorian.png', 69 | }, 70 | { 71 | xws: 'q90', 72 | name: 'Q9-0', 73 | initiative: 5, 74 | limited: 1, 75 | cost: 6, 76 | loadout: 16, 77 | ability: 78 | 'After you fully execute an advanced maneuver, you may perform a [Calculate] or [Barrel Roll] action, even while stressed. If you do, gain 1 strain token.', 79 | shipActions: [ 80 | { difficulty: 'White', type: 'Calculate' }, 81 | { difficulty: 'White', type: 'Evade' }, 82 | { difficulty: 'White', type: 'Lock' }, 83 | { difficulty: 'Red', type: 'Barrel Roll' }, 84 | ], 85 | slots: ['Crew', 'Gunner', 'Illicit', 'Illicit', 'Modification', 'Title'], 86 | standard: true, 87 | epic: true, 88 | extended: true, 89 | caption: 'Zero', 90 | keywords: ['Droid'], 91 | image: 'https://infinitearenas.com/xw2/images/pilots/q90.png', 92 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/q90.png', 93 | }, 94 | { 95 | xws: 'guildbountyhunter', 96 | name: 'Guild Bounty Hunter', 97 | initiative: 3, 98 | limited: 2, 99 | cost: 6, 100 | loadout: 14, 101 | ability: 102 | 'While you perform an attack at attack range 1-2, you may spend 1 non-recurring [Charge] from 1 of your equipped [Illicit] upgrades to change 1 [Focus] result to a [Crit] result.', 103 | slots: ['Talent', 'Crew', 'Gunner', 'Illicit', 'Illicit', 'Modification'], 104 | standard: true, 105 | epic: true, 106 | extended: true, 107 | caption: 'Blaster for Hire', 108 | keywords: ['Bounty Hunter'], 109 | image: 110 | 'https://infinitearenas.com/xw2/images/pilots/guildbountyhunter.png', 111 | artwork: 112 | 'https://infinitearenas.com/xw2/images/artwork/pilots/guildbountyhunter.png', 113 | }, 114 | { 115 | xws: 'outerrimenforcer', 116 | name: 'Outer Rim Enforcer', 117 | initiative: 2, 118 | limited: 0, 119 | cost: 6, 120 | loadout: 10, 121 | slots: ['Crew', 'Gunner', 'Illicit', 'Modification', 'Modification'], 122 | standard: true, 123 | epic: true, 124 | extended: true, 125 | image: 126 | 'https://infinitearenas.com/xw2/images/pilots/outerrimenforcer.png', 127 | artwork: 128 | 'https://infinitearenas.com/xw2/images/artwork/pilots/outerrimenforcer.png', 129 | }, 130 | ], 131 | icon: 132 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_ST-70.png', 133 | }; 134 | 135 | export default t; 136 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/trident-class-assault-ship.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Trident-class Assault Ship', 5 | xws: 'tridentclassassaultship', 6 | size: 'Huge', 7 | dial: [], 8 | faction: 'Scum and Villainy', 9 | stats: [ 10 | { arc: 'Front Arc', type: 'attack', value: 3 }, 11 | { type: 'hull', value: 10 }, 12 | { type: 'shields', value: 4, recovers: 1 }, 13 | { type: 'energy', value: 3, recovers: 2 }, 14 | ], 15 | actions: [ 16 | { type: 'Focus', difficulty: 'White' }, 17 | { type: 'Evade', difficulty: 'Red' }, 18 | { type: 'Reinforce', difficulty: 'Red' }, 19 | { type: 'Lock', difficulty: 'White' }, 20 | { type: 'Coordinate', difficulty: 'Red' }, 21 | ], 22 | pilots: [ 23 | { 24 | xws: 'lawlesspirates', 25 | ffg: 950, 26 | name: 'Lawless Pirates', 27 | cost: 85, 28 | limited: 0, 29 | initiative: 8, 30 | slots: [ 31 | 'Torpedo', 32 | 'Hardpoint', 33 | 'Hardpoint', 34 | 'Crew', 35 | 'Crew', 36 | 'Team', 37 | 'Cargo', 38 | 'Title', 39 | 'Gunner', 40 | 'Command', 41 | ], 42 | standard: false, 43 | extended: false, 44 | epic: true, 45 | text: 46 | 'The Separatist Alliance has close ties with certain mercenaries and criminal groups and, as the war rages on, its technology sometimes finds its way into unsavory hands.', 47 | artwork: 48 | 'https://infinitearenas.com/xw2/images/artwork/pilots/lawlesspirates.png', 49 | image: 'https://infinitearenas.com/xw2/images/pilots/lawlesspirates.png', 50 | }, 51 | ], 52 | icon: 53 | 'https://infinitearenas.com/xw2/images/shipicons/scum-and-villainy/I_Trident.png', 54 | }; 55 | 56 | export default t; 57 | -------------------------------------------------------------------------------- /src/assets/pilots/scum-and-villainy/yt-2400-light-freighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'YT-2400 Light Freighter', 5 | xws: 'yt2400lightfreighter', 6 | ffg: 5, 7 | size: 'Large', 8 | dial: [ 9 | '1TW', 10 | '1BB', 11 | '1FB', 12 | '1NB', 13 | '1YW', 14 | '2TW', 15 | '2BW', 16 | '2FB', 17 | '2NW', 18 | '2YW', 19 | '3TW', 20 | '3BW', 21 | '3FW', 22 | '3NW', 23 | '3YW', 24 | '4FW', 25 | '4KR', 26 | ], 27 | faction: 'Scum and Villainy', 28 | stats: [ 29 | { arc: 'Double Turret Arc', type: 'attack', value: 4 }, 30 | { type: 'agility', value: 2 }, 31 | { type: 'hull', value: 6 }, 32 | { type: 'shields', value: 4 }, 33 | ], 34 | actions: [ 35 | { difficulty: 'White', type: 'Focus' }, 36 | { difficulty: 'White', type: 'Lock' }, 37 | { difficulty: 'Red', type: 'Barrel Roll' }, 38 | { difficulty: 'White', type: 'Rotate Arc' }, 39 | ], 40 | ability: { 41 | name: 'Sensor Blindspot', 42 | text: 43 | 'While you perform a primary attack at attack range 0-1, do not apply the range 0-1 bonus and roll 1 fewer attack die.', 44 | }, 45 | icon: 46 | 'https://infinitearenas.com/xw2/images/shipicons/rebel-alliance/I_YT-2400.png', 47 | pilots: [ 48 | { 49 | name: '"Leebo"', 50 | caption: "He Thinks He's Funny", 51 | initiative: 3, 52 | limited: 1, 53 | cost: 6, 54 | xws: 'leebo-swz103-sl-scumandvillainy', 55 | ability: 56 | 'At the end of the Engagement Phase, you may spend a calculate token to acquire a lock on an enemy ship at range 2-3.', 57 | shipAbility: { 58 | name: 'Sensor Blackout', 59 | text: 60 | 'While you perform a primary attack at range 0-1, you roll 1 fewer attack die.\n\nWhile you defend at range 1, you roll 1 fewer defense die.', 61 | }, 62 | slots: [], 63 | standard: true, 64 | extended: true, 65 | epic: true, 66 | standardLoadout: ['efficientprocessing', 'seekermissiles', 'outrider'], 67 | stats: [ 68 | { arc: 'Double Turret Arc', type: 'attack', value: 3 }, 69 | { type: 'agility', value: 2 }, 70 | { type: 'hull', value: 6 }, 71 | { type: 'shields', value: 4 }, 72 | ], 73 | image: 74 | 'https://infinitearenas.com/xw2/images/quickbuilds/leebo-hethinkshesfunny-scumandvillainy.png', 75 | artwork: 'https://infinitearenas.com/xw2/images/artwork/pilots/leebo.png', 76 | }, 77 | { 78 | name: 'Dash Rendar', 79 | caption: 'In it for Himself', 80 | initiative: 5, 81 | limited: 1, 82 | cost: 7, 83 | xws: 'dashrendar-swz103-sl-scumandvillainy', 84 | ability: 85 | 'After you gain a red token as a result of moving through or overlapping an obstacle, you may transfer that red token to a friendly ship at range 0-1.', 86 | shipAbility: { 87 | name: 'Sensor Blackout', 88 | text: 89 | 'While you perform a primary attack at range 0-1, you roll 1 fewer attack die.\n\nWhile you defend at range 1, you roll 1 fewer defense die.', 90 | }, 91 | slots: [], 92 | standard: true, 93 | extended: true, 94 | epic: true, 95 | standardLoadout: ['mercenary', 'seekermissiles', 'leebo', 'outrider'], 96 | stats: [ 97 | { arc: 'Double Turret Arc', type: 'attack', value: 3 }, 98 | { type: 'agility', value: 2 }, 99 | { type: 'hull', value: 6 }, 100 | { type: 'shields', value: 4 }, 101 | ], 102 | image: 103 | 'https://infinitearenas.com/xw2/images/quickbuilds/dashrendar-initforhimself-scumandvillainy.png', 104 | artwork: 105 | 'https://infinitearenas.com/xw2/images/artwork/pilots/dashrendar.png', 106 | }, 107 | ], 108 | }; 109 | 110 | export default t; 111 | -------------------------------------------------------------------------------- /src/assets/pilots/separatist-alliance/c-roc-cruiser.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'C-ROC Cruiser', 5 | xws: 'croccruiser', 6 | size: 'Huge', 7 | dial: [ 8 | '0BR', 9 | '0OR', 10 | '0NR', 11 | '1BW', 12 | '1NW', 13 | '1FB', 14 | '2BW', 15 | '2NW', 16 | '2FB', 17 | '3NR', 18 | '3FW', 19 | '3BR', 20 | '4FR', 21 | '5FR', 22 | ], 23 | faction: 'Separatist Alliance', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { type: 'agility', value: 0 }, 27 | { type: 'hull', value: 12 }, 28 | { type: 'shields', value: 4, recovers: 1 }, 29 | { type: 'energy', value: 4, recovers: 1 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'White', type: 'Lock' }, 34 | { difficulty: 'White', type: 'Reinforce' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | { difficulty: 'White', type: 'Jam' }, 37 | ], 38 | ability: { 39 | name: 'Overdrive Burners', 40 | text: 41 | 'While you defend, if your revealed maneuver is speed 3-5, roll 1 additional defense die.', 42 | }, 43 | pilots: [ 44 | { 45 | name: 'Separatist Privateers', 46 | text: 47 | 'The Separatist Alliance makes use of all manner of unsavory contacts in its fight against the Galactic Republic, including corsairs and criminal cartels.', 48 | initiative: 7, 49 | engagement: 1, 50 | limited: 0, 51 | cost: 63, 52 | xws: 'separatistprivateers', 53 | slots: [ 54 | 'Command', 55 | 'Hardpoint', 56 | 'Crew', 57 | 'Crew', 58 | 'Tactical Relay', 59 | 'Team', 60 | 'Cargo', 61 | 'Device', 62 | 'Configuration', 63 | ], 64 | standard: false, 65 | extended: false, 66 | epic: true, 67 | ffg: 714, 68 | artwork: 69 | 'https://infinitearenas.com/xw2/images/artwork/pilots/separatistprivateers.png', 70 | image: 71 | 'https://infinitearenas.com/xw2/images/pilots/separatistprivateers.png', 72 | }, 73 | ], 74 | ffg: 82, 75 | icon: 76 | 'https://infinitearenas.com/xw2/images/shipicons/separatist-alliance/I_C-ROC.png', 77 | }; 78 | 79 | export default t; 80 | -------------------------------------------------------------------------------- /src/assets/pilots/separatist-alliance/gauntlet-fighter.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Gauntlet Fighter', 5 | xws: 'gauntletfighter', 6 | size: 'Large', 7 | dial: [ 8 | '0OR', 9 | '1BB', 10 | '1NB', 11 | '2TW', 12 | '2BB', 13 | '2FB', 14 | '2NB', 15 | '2YW', 16 | '3TR', 17 | '3BW', 18 | '3FW', 19 | '3NW', 20 | '3YR', 21 | '4FW', 22 | ], 23 | faction: 'Separatist Alliance', 24 | stats: [ 25 | { arc: 'Front Arc', type: 'attack', value: 3 }, 26 | { arc: 'Rear Arc', type: 'attack', value: 2 }, 27 | { type: 'agility', value: 2 }, 28 | { type: 'hull', value: 9 }, 29 | { type: 'shields', value: 2 }, 30 | ], 31 | actions: [ 32 | { difficulty: 'White', type: 'Focus' }, 33 | { difficulty: 'Red', type: 'Reinforce' }, 34 | { difficulty: 'White', type: 'Lock' }, 35 | { difficulty: 'Red', type: 'Coordinate' }, 36 | ], 37 | pilots: [ 38 | { 39 | xws: 'bokatankryze-separatistalliance', 40 | name: 'Bo-Katan Kryze', 41 | caption: "Vizsla's Lieutenant", 42 | ability: 43 | 'Before a friendly ship at range 0-2 activates, you may spend 1 [Charge]. If you do, that ship may gain 1 strain token to remove 1 non-stress red or orange token.', 44 | cost: 6, 45 | loadout: 12, 46 | initiative: 4, 47 | limited: 1, 48 | standard: true, 49 | extended: true, 50 | epic: true, 51 | slots: [ 52 | 'Talent', 53 | 'Crew', 54 | 'Gunner', 55 | 'Device', 56 | 'Illicit', 57 | 'Modification', 58 | 'Modification', 59 | 'Configuration', 60 | 'Title', 61 | ], 62 | keywords: ['Mandalorian'], 63 | image: 64 | 'https://infinitearenas.com/xw2/images/pilots/bokatankryze-separatist-alliance.png', 65 | artwork: 66 | 'https://infinitearenas.com/xw2/images/artwork/pilots/bokatankryze-separatist-alliance.png', 67 | }, 68 | { 69 | xws: 'previzsla', 70 | name: 'Pre Vizsla', 71 | cost: 6, 72 | loadout: 14, 73 | initiative: 3, 74 | limited: 1, 75 | ability: 76 | "While you perform an attack, if the defender's initiative is equal to or greater than yours, you may spend 2 to roll 1 additional die.", 77 | standard: true, 78 | extended: true, 79 | epic: true, 80 | slots: [ 81 | 'Talent', 82 | 'Crew', 83 | 'Gunner', 84 | 'Device', 85 | 'Illicit', 86 | 'Modification', 87 | 'Configuration', 88 | ], 89 | keywords: ['Mandalorian'], 90 | caption: 'Leader of Death Watch', 91 | image: 'https://infinitearenas.com/xw2/images/pilots/previzsla.png', 92 | artwork: 93 | 'https://infinitearenas.com/xw2/images/artwork/pilots/previzsla.png', 94 | }, 95 | { 96 | xws: 'deathwatchwarrior', 97 | name: 'Death Watch Warrior', 98 | cost: 7, 99 | loadout: 10, 100 | initiative: 1, 101 | limited: 0, 102 | standard: true, 103 | extended: true, 104 | epic: true, 105 | slots: [ 106 | 'Talent', 107 | 'Crew', 108 | 'Gunner', 109 | 'Device', 110 | 'Illicit', 111 | 'Modification', 112 | 'Configuration', 113 | ], 114 | keywords: ['Mandalorian'], 115 | caption: 'Fanatical Adherent', 116 | image: 117 | 'https://infinitearenas.com/xw2/images/pilots/deathwatchwarrior.png', 118 | artwork: 119 | 'https://infinitearenas.com/xw2/images/artwork/pilots/deathwatchwarrior.png', 120 | }, 121 | ], 122 | }; 123 | 124 | export default t; 125 | -------------------------------------------------------------------------------- /src/assets/pilots/separatist-alliance/index.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | import belbullab22starfighter from './belbullab-22-starfighter'; 3 | import croccruiser from './c-roc-cruiser'; 4 | import hyenaclassdroidbomber from './hyena-class-droid-bomber'; 5 | import nantexclassstarfighter from './nantex-class-starfighter'; 6 | import sithinfiltrator from './sith-infiltrator'; 7 | import vultureclassdroidfighter from './vulture-class-droid-fighter'; 8 | import droidtrifighter from './droid-tri-fighter'; 9 | import firesprayclasspatrolcraft from './firespray-class-patrol-craft'; 10 | import hmpdroidgunship from './hmp-droid-gunship'; 11 | import tridentclassassaultship from './trident-class-assault-ship'; 12 | import gauntletfighter from './gauntlet-fighter'; 13 | import rogueclassstarfighter from './rogue-class-starfighter' 14 | 15 | const ships: { [s: string]: ShipType } = { 16 | belbullab22starfighter, 17 | croccruiser, 18 | hyenaclassdroidbomber, 19 | nantexclassstarfighter, 20 | sithinfiltrator, 21 | vultureclassdroidfighter, 22 | droidtrifighter, 23 | firesprayclasspatrolcraft, 24 | hmpdroidgunship, 25 | tridentclassassaultship, 26 | gauntletfighter, 27 | rogueclassstarfighter 28 | }; 29 | 30 | export default ships; 31 | -------------------------------------------------------------------------------- /src/assets/pilots/separatist-alliance/trident-class-assault-ship.ts: -------------------------------------------------------------------------------- 1 | import { ShipType } from '../../../types'; 2 | 3 | const t: ShipType = { 4 | name: 'Trident-class Assault Ship', 5 | xws: 'tridentclassassaultship', 6 | size: 'Huge', 7 | dial: [], 8 | faction: 'Separatist Alliance', 9 | stats: [ 10 | { arc: 'Front Arc', type: 'attack', value: 3 }, 11 | { type: 'hull', value: 10 }, 12 | { type: 'shields', value: 4, recovers: 1 }, 13 | { type: 'energy', value: 3, recovers: 2 }, 14 | ], 15 | actions: [ 16 | { type: 'Focus', difficulty: 'White' }, 17 | { type: 'Evade', difficulty: 'Red' }, 18 | { type: 'Reinforce', difficulty: 'Red' }, 19 | { type: 'Lock', difficulty: 'White' }, 20 | { type: 'Coordinate', difficulty: 'Red' }, 21 | ], 22 | pilots: [ 23 | { 24 | xws: 'colicoiddestroyer', 25 | name: 'Colicoid Destroyer', 26 | cost: 85, 27 | initiative: 8, 28 | limited: 0, 29 | slots: [ 30 | 'Torpedo', 31 | 'Hardpoint', 32 | 'Hardpoint', 33 | 'Crew', 34 | 'Crew', 35 | 'Team', 36 | 'Cargo', 37 | 'Title', 38 | 'Gunner', 39 | 'Command', 40 | ], 41 | standard: false, 42 | extended: false, 43 | epic: true, 44 | ffg: 949, 45 | text: 46 | 'Designed by the Colicoid Creation Nest and equipped with powerful tentacles and a massive drill to tear though the hull of even the toughest starships and fortifications, the Trident-class Assault Ship is a terrifying testament to the threat posed by the Separatist Alliance.', 47 | artwork: 48 | 'https://infinitearenas.com/xw2/images/artwork/pilots/colicoiddestroyer.png', 49 | image: 50 | 'https://infinitearenas.com/xw2/images/pilots/colicoiddestroyer.png', 51 | }, 52 | ], 53 | icon: 54 | 'https://infinitearenas.com/xw2/images/shipicons/separatist-alliance/I_Trident.png', 55 | }; 56 | 57 | export default t; 58 | -------------------------------------------------------------------------------- /src/assets/sources/additional-pilots.ts: -------------------------------------------------------------------------------- 1 | import { Source } from '../../types'; 2 | 3 | export const t: Source[] = []; 4 | 5 | export default t; 6 | -------------------------------------------------------------------------------- /src/assets/sources/additional-ships.ts: -------------------------------------------------------------------------------- 1 | import { Source } from '../../types'; 2 | 3 | export const t: Source[] = []; 4 | 5 | export default t; 6 | -------------------------------------------------------------------------------- /src/assets/sources/additional-upgrades.ts: -------------------------------------------------------------------------------- 1 | import { Source } from '../../types'; 2 | 3 | export const t: Source[] = []; 4 | 5 | export default t; 6 | -------------------------------------------------------------------------------- /src/assets/sources/index.ts: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { Faction, Source } from '../../types'; 3 | import { t as coreSets } from './core-sets'; 4 | import { t as epic } from './epic'; 5 | import { t as firstOrder } from './first-order'; 6 | import { t as galacticEmpire } from './galactic-empire'; 7 | import { t as galacticRepublic } from './galactic-republic'; 8 | import { t as rebelAlliance } from './rebel-alliance'; 9 | import { t as resistance } from './resistance'; 10 | import { t as scumAndVillainy } from './scum-and-villainy'; 11 | import { t as separatistAlliance } from './separatist-alliance'; 12 | 13 | export type SourceKey = 14 | | Faction 15 | | 'Core Sets' 16 | | 'Additional Ships' 17 | | 'Additional Pilots' 18 | | 'Additional Upgrades' 19 | | 'Epic'; 20 | 21 | const t: { [key in SourceKey]: Source[] } = { 22 | 'Core Sets': coreSets, 23 | 'First Order': firstOrder, 24 | 'Galactic Empire': galacticEmpire, 25 | 'Galactic Republic': galacticRepublic, 26 | 'Rebel Alliance': rebelAlliance, 27 | Resistance: resistance, 28 | 'Scum and Villainy': scumAndVillainy, 29 | 'Separatist Alliance': separatistAlliance, 30 | Epic: epic, 31 | 'Additional Pilots': [], 32 | 'Additional Ships': [], 33 | 'Additional Upgrades': [], 34 | }; 35 | 36 | export default t; 37 | -------------------------------------------------------------------------------- /src/assets/upgrades/cargo.ts: -------------------------------------------------------------------------------- 1 | import { UpgradeBase } from '../../types'; 2 | 3 | const t: UpgradeBase[] = [ 4 | { 5 | limited: 0, 6 | xws: 'adaptiveshields', 7 | sides: [ 8 | { 9 | ability: 10 | 'While another friendly ship at range 0-1 defends, if it is a smaller size than you, you may spend 1 shield or 2 [Energy] to cancel 1 [Hit] or [Critical Hit] result.', 11 | title: 'Adaptive Shields', 12 | type: 'Cargo', 13 | slots: ['Cargo'], 14 | image: 15 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/adaptiveshields.png', 16 | artwork: 17 | 'https://infinitearenas.com/xw2/images/upgrades/adaptiveshields.png', 18 | }, 19 | ], 20 | cost: { value: 5 }, 21 | standard: false, 22 | epic: true, 23 | }, 24 | { 25 | limited: 0, 26 | xws: 'boostedscanners', 27 | sides: [ 28 | { 29 | ability: 30 | 'While you lock, coordinate, or jam, you may spend up to 3 [Energy] to increase the range at which you can choose an object by 1 per [Energy] spent this way, to a maximum of range 5.', 31 | title: 'Boosted Scanners', 32 | type: 'Cargo', 33 | slots: ['Cargo'], 34 | image: 35 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/boostedscanners.png', 36 | artwork: 37 | 'https://infinitearenas.com/xw2/images/upgrades/boostedscanners.png', 38 | }, 39 | ], 40 | cost: { value: 7 }, 41 | standard: false, 42 | epic: true, 43 | }, 44 | { 45 | limited: 0, 46 | xws: 'optimizedpowercore', 47 | sides: [ 48 | { 49 | ability: 'After you execute a blue maneuver, recover 1 [Energy].', 50 | title: 'Optimized Power Core', 51 | type: 'Cargo', 52 | slots: ['Cargo'], 53 | image: 54 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/optimizedpowercore.png', 55 | artwork: 56 | 'https://infinitearenas.com/xw2/images/upgrades/optimizedpowercore.png', 57 | }, 58 | ], 59 | cost: { value: 6 }, 60 | standard: false, 61 | epic: true, 62 | }, 63 | { 64 | limited: 0, 65 | xws: 'tibannareserves', 66 | sides: [ 67 | { 68 | ability: 'Action: Spend 1 [Charge] to recover 2 [Energy].', 69 | title: 'Tibanna Reserves', 70 | type: 'Cargo', 71 | slots: ['Cargo'], 72 | charges: { value: 3, recovers: 0 }, 73 | image: 74 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/tibannareserves.png', 75 | artwork: 76 | 'https://infinitearenas.com/xw2/images/upgrades/tibannareserves.png', 77 | }, 78 | ], 79 | cost: { value: 3 }, 80 | standard: false, 81 | epic: true, 82 | }, 83 | ]; 84 | 85 | export default t; 86 | -------------------------------------------------------------------------------- /src/assets/upgrades/hyperdrive.ts: -------------------------------------------------------------------------------- 1 | import { UpgradeBase } from '../../types'; 2 | 3 | const t: UpgradeBase[] = [ 4 | { 5 | xws: 'syliure31hyperdrive', 6 | limited: 0, 7 | cost: { value: 0 }, 8 | sides: [ 9 | { 10 | title: 'Syliure-31 Hyperdrive', 11 | type: 'Hyperdrive', 12 | ability: 13 | 'Setup: You can be placed anywhere in the play area beyond range 1 of obstacles, beyond range 3 of enemy ships, and beyond range 3 of the enemy table edge.', 14 | slots: ['Hyperdrive'], 15 | ffg: 850, 16 | artwork: 17 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/syliure31hyperdrive.png', 18 | image: 19 | 'https://infinitearenas.com/xw2/images/upgrades/syliure31hyperdrive.png', 20 | }, 21 | ], 22 | standard: false, 23 | epic: true, 24 | }, 25 | ]; 26 | 27 | export default t; 28 | -------------------------------------------------------------------------------- /src/assets/upgrades/index.ts: -------------------------------------------------------------------------------- 1 | import astromech from './astromech'; 2 | import cannon from './cannon'; 3 | import cargo from './cargo'; 4 | import command from './command'; 5 | import configuration from './configuration'; 6 | import crew from './crew'; 7 | import device from './device'; 8 | import forcepower from './force-power'; 9 | import gunner from './gunner'; 10 | import hardpoint from './hardpoint'; 11 | import illicit from './illicit'; 12 | import missile from './missile'; 13 | import modification from './modification'; 14 | import sensor from './sensor'; 15 | import tacticalrelay from './tactical-relay'; 16 | import talent from './talent'; 17 | import team from './team'; 18 | import tech from './tech'; 19 | import title from './title'; 20 | import torpedo from './torpedo'; 21 | import turret from './turret'; 22 | import hyperdrive from './hyperdrive'; 23 | 24 | export default { 25 | astromech, 26 | cannon, 27 | cargo, 28 | command, 29 | configuration, 30 | crew, 31 | device, 32 | forcepower, 33 | gunner, 34 | hardpoint, 35 | hyperdrive, 36 | illicit, 37 | missile, 38 | modification, 39 | sensor, 40 | tacticalrelay, 41 | talent, 42 | team, 43 | tech, 44 | title, 45 | torpedo, 46 | turret, 47 | }; 48 | -------------------------------------------------------------------------------- /src/assets/upgrades/sensor.ts: -------------------------------------------------------------------------------- 1 | import { UpgradeBase } from '../../types'; 2 | 3 | const t: UpgradeBase[] = [ 4 | { 5 | limited: 0, 6 | xws: 'advancedsensors', 7 | sides: [ 8 | { 9 | title: 'Advanced Sensors', 10 | type: 'Sensor', 11 | ability: 12 | 'After you reveal your dial, you may perform 1 action. If you do, you cannot perform another action during your activation.', 13 | slots: ['Sensor'], 14 | image: 15 | 'https://infinitearenas.com/xw2/images/upgrades/advancedsensors.png', 16 | artwork: 17 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/advancedsensors.png', 18 | ffg: 252, 19 | }, 20 | ], 21 | cost: { value: 12 }, 22 | standard: false, 23 | epic: true, 24 | extended: true, 25 | }, 26 | { 27 | limited: 0, 28 | xws: 'collisiondetector', 29 | sides: [ 30 | { 31 | title: 'Collision Detector', 32 | type: 'Sensor', 33 | ability: 34 | 'While you boost or barrel roll, you can move through and overlap obstacles. After you move through or overlap an obstacle, you may spend 1 [Charge] to ignore its effects until the end of the round.', 35 | slots: ['Sensor'], 36 | charges: { value: 2, recovers: 0 }, 37 | image: 38 | 'https://infinitearenas.com/xw2/images/upgrades/collisiondetector.png', 39 | artwork: 40 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/collisiondetector.png', 41 | ffg: 253, 42 | }, 43 | ], 44 | cost: { value: 7 }, 45 | standard: true, 46 | epic: true, 47 | extended: true, 48 | }, 49 | { 50 | limited: 0, 51 | xws: 'firecontrolsystem', 52 | sides: [ 53 | { 54 | title: 'Fire-Control System', 55 | type: 'Sensor', 56 | ability: 57 | 'While you perform an attack, if you have a lock on the defender, you may reroll 1 attack die. If you do, you cannot spend your lock during this attack.', 58 | slots: ['Sensor'], 59 | image: 60 | 'https://infinitearenas.com/xw2/images/upgrades/firecontrolsystem.png', 61 | artwork: 62 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/firecontrolsystem.png', 63 | ffg: 254, 64 | }, 65 | ], 66 | cost: { value: 2 }, 67 | standard: true, 68 | epic: true, 69 | extended: true, 70 | }, 71 | { 72 | limited: 0, 73 | xws: 'trajectorysimulator', 74 | sides: [ 75 | { 76 | title: 'Trajectory Simulator', 77 | type: 'Sensor', 78 | ability: 79 | 'During the System Phase, if you would drop or launch a bomb, you may launch it using the (5 [Straight]) template instead.', 80 | slots: ['Sensor'], 81 | image: 82 | 'https://infinitearenas.com/xw2/images/upgrades/trajectorysimulator.png', 83 | artwork: 84 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/trajectorysimulator.png', 85 | ffg: 255, 86 | }, 87 | ], 88 | cost: { value: 8 }, 89 | standard: false, 90 | epic: true, 91 | extended: true, 92 | }, 93 | { 94 | limited: 0, 95 | xws: 'passivesensors', 96 | sides: [ 97 | { 98 | ability: 99 | 'Action: Spend 1 [Charge]. You can only perform this action in your Perform Action step. While your [Charge] is inactive, you cannot be coordinated. Before you engage, if your [Charge] is inactive, you may perform a [Calculate] or [Lock] action.', 100 | title: 'Passive Sensors', 101 | type: 'Sensor', 102 | slots: ['Sensor'], 103 | charges: { value: 1, recovers: 1 }, 104 | ffg: 577, 105 | artwork: 106 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/passivesensors.png', 107 | image: 108 | 'https://infinitearenas.com/xw2/images/upgrades/passivesensors.png', 109 | }, 110 | ], 111 | cost: { value: 5 }, 112 | standard: true, 113 | epic: true, 114 | extended: true, 115 | }, 116 | { 117 | limited: 0, 118 | xws: 'blanksignature-battleoverendor', 119 | sides: [ 120 | { 121 | ability: 122 | 'While defending, if you are not locked by the attacker, you may spend 1 [Focus] to change 1 result to an [Evade] result.', 123 | title: 'Blank Signature', 124 | type: 'Sensor', 125 | slots: ['Sensor'], 126 | charges: { value: 1, recovers: 1 }, 127 | }, 128 | ], 129 | cost: { value: 0 }, 130 | standard: true, 131 | epic: true, 132 | extended: true, 133 | standardLoadoutOnly: true, 134 | }, 135 | ]; 136 | 137 | export default t; 138 | -------------------------------------------------------------------------------- /src/assets/upgrades/tactical-relay.ts: -------------------------------------------------------------------------------- 1 | import { UpgradeBase } from '../../types'; 2 | 3 | const t: UpgradeBase[] = [ 4 | { 5 | limited: 1, 6 | xws: 'kraken', 7 | sides: [ 8 | { 9 | title: 'Kraken', 10 | type: 'Tactical Relay', 11 | ability: 12 | 'During the End Phase, you may choose up to 3 friendly ships at range 0-3. If you do, each of these ships does not remove 1 calculate token.', 13 | slots: ['Tactical Relay'], 14 | ffg: 531, 15 | grants: [ 16 | { action: { type: 'Calculate', difficulty: 'White' }, value: 1 }, 17 | ], 18 | artwork: 19 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/kraken.png', 20 | image: 'https://infinitearenas.com/xw2/images/upgrades/kraken.png', 21 | }, 22 | ], 23 | restrictions: [{ factions: ['Separatist Alliance'] }], 24 | standard: true, 25 | epic: true, 26 | cost: { value: 8 }, 27 | extended: true, 28 | }, 29 | { 30 | xws: 'tv94', 31 | limited: 1, 32 | sides: [ 33 | { 34 | title: 'TV-94', 35 | type: 'Tactical Relay', 36 | ability: 37 | 'While a friendly ship at range 0-3 performs a primary attack against a defender in its [Bullseye Arc], if there are 2 or fewer attack dice, it may spend 1 calculate token to add 1 [Hit] result.', 38 | slots: ['Tactical Relay'], 39 | ffg: 530, 40 | artwork: 41 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/tv94.png', 42 | image: 'https://infinitearenas.com/xw2/images/upgrades/tv94.png', 43 | }, 44 | ], 45 | restrictions: [{ factions: ['Separatist Alliance'] }], 46 | cost: { value: 3 }, 47 | standard: true, 48 | epic: true, 49 | extended: true, 50 | }, 51 | { 52 | xws: 'k2b4', 53 | limited: 1, 54 | sides: [ 55 | { 56 | title: 'K2-B4', 57 | type: 'Tactical Relay', 58 | ability: 59 | 'While a friendly ship at range 0-3 defends, it may spend 1 calculate token. If it does, add 1 [Evade] result unless the attacker chooses to gain 1 strain token.', 60 | slots: ['Tactical Relay'], 61 | ffg: 537, 62 | artwork: 63 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/k2b4.png', 64 | image: 'https://infinitearenas.com/xw2/images/upgrades/k2b4.png', 65 | }, 66 | ], 67 | restrictions: [{ factions: ['Separatist Alliance'] }], 68 | cost: { value: 4 }, 69 | standard: true, 70 | epic: true, 71 | extended: true, 72 | }, 73 | { 74 | xws: 'ta175', 75 | limited: 1, 76 | sides: [ 77 | { 78 | title: 'TA-175', 79 | type: 'Tactical Relay', 80 | ability: 81 | 'After a friendly ship at range 0-3 with [Calculate] on its action bar is destroyed, each friendly ship at range 0-3 with [Calculate] in its action bar gains 1 calculate token.', 82 | slots: ['Tactical Relay'], 83 | ffg: 590, 84 | artwork: 85 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/ta175.png', 86 | image: 'https://infinitearenas.com/xw2/images/upgrades/ta175.png', 87 | }, 88 | ], 89 | restrictions: [{ factions: ['Separatist Alliance'] }], 90 | standard: true, 91 | epic: true, 92 | cost: { value: 6 }, 93 | extended: true, 94 | }, 95 | { 96 | xws: 'kalani', 97 | limited: 1, 98 | cost: { value: 3 }, 99 | sides: [ 100 | { 101 | ffg: 682, 102 | title: 'Kalani', 103 | type: 'Tactical Relay', 104 | slots: ['Tactical Relay'], 105 | ability: 106 | 'After an enemy ship executes a maneuver, if it is in the [Bullseye Arc] of a friendly ship at range 0-3, you may spend 1 [Charge]. If you do, that friendly ship acquires a lock on that enemy ship, then gains 1 stress token.', 107 | charges: { value: 3, recovers: 3 }, 108 | grants: [ 109 | { action: { type: 'Calculate', difficulty: 'White' }, value: 1 }, 110 | ], 111 | artwork: 112 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/kalani.png', 113 | image: 'https://infinitearenas.com/xw2/images/upgrades/kalani.png', 114 | }, 115 | ], 116 | standard: true, 117 | epic: true, 118 | restrictions: [{ factions: ['Separatist Alliance'] }], 119 | extended: true, 120 | }, 121 | ]; 122 | 123 | export default t; 124 | -------------------------------------------------------------------------------- /src/assets/upgrades/turret.ts: -------------------------------------------------------------------------------- 1 | import { UpgradeBase } from '../../types'; 2 | 3 | const t: UpgradeBase[] = [ 4 | { 5 | limited: 0, 6 | xws: 'dorsalturret', 7 | sides: [ 8 | { 9 | title: 'Dorsal Turret', 10 | type: 'Turret', 11 | ability: 'Attack', 12 | slots: ['Turret'], 13 | attack: { 14 | arc: 'Single Turret Arc', 15 | value: 2, 16 | minrange: 1, 17 | maxrange: 2, 18 | ordnance: false, 19 | }, 20 | actions: [{ type: 'Rotate Arc', difficulty: 'White' }], 21 | grants: [ 22 | { action: { type: 'Rotate Arc', difficulty: 'White' }, value: 1 }, 23 | ], 24 | image: 25 | 'https://infinitearenas.com/xw2/images/upgrades/dorsalturret.png', 26 | artwork: 27 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/dorsalturret.png', 28 | ffg: 260, 29 | }, 30 | ], 31 | cost: { value: 2 }, 32 | standard: true, 33 | epic: true, 34 | extended: true, 35 | }, 36 | { 37 | limited: 0, 38 | xws: 'ioncannonturret', 39 | sides: [ 40 | { 41 | title: 'Ion Cannon Turret', 42 | type: 'Turret', 43 | ability: 44 | 'Attack: If this attack hits, spend 1 [Hit] or [Critical Hit] result to cause the defender to suffer 1 [Hit] damage. All remaining [Hit]/[Critical Hit] results inflict ion tokens instead of damage.', 45 | image: 46 | 'https://infinitearenas.com/xw2/images/upgrades/ioncannonturret.png', 47 | slots: ['Turret'], 48 | attack: { 49 | arc: 'Single Turret Arc', 50 | value: 3, 51 | minrange: 1, 52 | maxrange: 2, 53 | ordnance: false, 54 | }, 55 | actions: [{ type: 'Rotate Arc', difficulty: 'White' }], 56 | grants: [ 57 | { action: { type: 'Rotate Arc', difficulty: 'White' }, value: 1 }, 58 | ], 59 | artwork: 60 | 'https://infinitearenas.com/xw2/images/artwork/upgrades/ioncannonturret.png', 61 | ffg: 261, 62 | }, 63 | ], 64 | cost: { value: 5 }, 65 | standard: true, 66 | epic: true, 67 | extended: true, 68 | }, 69 | ]; 70 | 71 | export default t; 72 | -------------------------------------------------------------------------------- /src/helpers/convert.ts: -------------------------------------------------------------------------------- 1 | import { Slot, SlotKey, Squadron, SquadronXWS } from '../types'; 2 | import { allSlots, slotKeys } from './enums'; 3 | 4 | export const slotFromKey = (key: SlotKey): Slot => { 5 | const index = slotKeys.indexOf(key); 6 | if (index >= 0) { 7 | return allSlots[index]; 8 | } 9 | return 'Force Power'; 10 | }; 11 | 12 | export const keyFromSlot = (slot: Slot): SlotKey => { 13 | const index = allSlots.indexOf(slot); 14 | if (index >= 0) { 15 | return slotKeys[index]; 16 | } 17 | return 'forcepower'; 18 | }; 19 | 20 | export const xwsFromSquadron = (squadron: Squadron): SquadronXWS => { 21 | const s = Object.assign({}, squadron); 22 | 23 | return { 24 | uid: s.uid, 25 | name: s.name, 26 | description: '', 27 | cost: s.cost, 28 | faction: s.faction, 29 | favourite: s.favourite, 30 | format: s.format, 31 | version: s.version, 32 | pilots: s.ships.map((ship) => { 33 | const upgrades: { [s: string]: string[] } = {}; 34 | slotKeys.forEach((key) => { 35 | const u = ship.upgrades && ship.upgrades[key]; 36 | if (u) { 37 | upgrades[key] = u.map((p) => p.xws); 38 | } 39 | }); 40 | 41 | return { 42 | uid: ship.uid, 43 | name: ship.pilot.xws, 44 | ship: ship.xws, 45 | upgrades, 46 | cost: ship.pointsWithUpgrades, 47 | }; 48 | }), 49 | }; 50 | }; 51 | -------------------------------------------------------------------------------- /src/helpers/enums.ts: -------------------------------------------------------------------------------- 1 | import { SourceKey } from '../assets/sources'; 2 | import { Faction, FactionKey, Format, Slot, SlotKey } from '../types'; 3 | 4 | export const factions: Faction[] = [ 5 | 'First Order', 6 | 'Galactic Empire', 7 | 'Galactic Republic', 8 | 'Rebel Alliance', 9 | 'Resistance', 10 | 'Scum and Villainy', 11 | 'Separatist Alliance', 12 | ]; 13 | 14 | export const factionKeys: FactionKey[] = [ 15 | 'firstorder', 16 | 'galacticempire', 17 | 'galacticrepublic', 18 | 'rebelalliance', 19 | 'resistance', 20 | 'scumandvillainy', 21 | 'separatistalliance', 22 | ]; 23 | 24 | export const sourceKeys: SourceKey[] = [ 25 | ...factions, 26 | 'Epic', 27 | 'Core Sets', 28 | 'Additional Ships', 29 | 'Additional Pilots', 30 | 'Additional Upgrades', 31 | ]; 32 | 33 | export const formats: Format[] = ['Standard', 'Extended', 'Epic']; 34 | 35 | export const allSlots: Slot[] = [ 36 | 'Astromech', 37 | 'Cannon', 38 | 'Cargo', 39 | 'Command', 40 | 'Configuration', 41 | 'Crew', 42 | 'Device', 43 | 'Force Power', 44 | 'Gunner', 45 | 'Hardpoint', 46 | 'Hyperdrive', 47 | 'Illicit', 48 | 'Missile', 49 | 'Modification', 50 | 'Sensor', 51 | 'Tactical Relay', 52 | 'Talent', 53 | 'Team', 54 | 'Tech', 55 | 'Title', 56 | 'Torpedo', 57 | 'Turret', 58 | ]; 59 | 60 | export const slotKeys: SlotKey[] = [ 61 | 'astromech', 62 | 'cannon', 63 | 'cargo', 64 | 'command', 65 | 'configuration', 66 | 'crew', 67 | 'device', 68 | 'forcepower', 69 | 'gunner', 70 | 'hardpoint', 71 | 'hyperdrive', 72 | 'illicit', 73 | 'missile', 74 | 'modification', 75 | 'sensor', 76 | 'tacticalrelay', 77 | 'talent', 78 | 'team', 79 | 'tech', 80 | 'title', 81 | 'torpedo', 82 | 'turret', 83 | ]; 84 | 85 | export const obstacles: string[] = [ 86 | 'obstacle-core2asteroid0', 87 | 'obstacle-core2asteroid1', 88 | 'obstacle-core2asteroid2', 89 | 'obstacle-core2asteroid3', 90 | 'obstacle-core2asteroid4', 91 | 'obstacle-core2asteroid5', 92 | 'obstacle-vt49decimatordebris0', 93 | 'obstacle-vt49decimatordebris1', 94 | 'obstacle-vt49decimatordebris2', 95 | 'obstacle-yt2400debris0', 96 | 'obstacle-yt2400debris1', 97 | 'obstacle-yt2400debris2', 98 | 'obstacle-gascloud1', 99 | 'obstacle-gascloud2', 100 | 'obstacle-gascloud3', 101 | 'obstacle-gascloud4', 102 | 'obstacle-gascloud5', 103 | 'obstacle-gascloud6', 104 | ]; 105 | -------------------------------------------------------------------------------- /src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | import * as Convert from './convert'; 2 | import * as Enums from './enums'; 3 | import * as Icon from './icon'; 4 | import * as ImportExport from './import+export'; 5 | import * as Serializer from './serializer'; 6 | import * as Text from './text'; 7 | import * as Unique from './unique'; 8 | import * as Unit from './unit'; 9 | import * as Versioning from './versioning'; 10 | 11 | export const convert = Convert; 12 | export const enums = Enums; 13 | export const icon = Icon; 14 | export const importExport = ImportExport; 15 | export const serializer = Serializer; 16 | export const text = Text; 17 | export const unique = Unique; 18 | export const unit = Unit; 19 | export const versioning = Versioning; 20 | 21 | export default { 22 | convert: Convert, 23 | enums: Enums, 24 | icon: Icon, 25 | importExport: ImportExport, 26 | serializer: Serializer, 27 | text: Text, 28 | unique: Unique, 29 | unit: Unit, 30 | versioning: Versioning, 31 | }; 32 | -------------------------------------------------------------------------------- /src/helpers/text.ts: -------------------------------------------------------------------------------- 1 | export type Content = { 2 | text: string; 3 | type: "text" | "strong" | "icon"; 4 | }; 5 | 6 | type Needle = { start: string; end: string; type: "text" | "strong" | "icon" }; 7 | 8 | export default (inText: string): Content[] => { 9 | if (!inText) { 10 | return []; 11 | } 12 | 13 | const replacedDegrees = inText.split("°").join("°"); 14 | const replacedLineBreaks = replacedDegrees.split("
").join("\n"); 15 | 16 | let cropText = replacedLineBreaks; 17 | const content: Array = []; 18 | 19 | const needles: Needle[] = [ 20 | { start: "", end: "", type: "strong" }, 21 | { start: "[", end: "]", type: "icon" }, 22 | ]; 23 | 24 | while (cropText.length > 0) { 25 | let closestNeedle: Needle | undefined; 26 | let closest = 9999; 27 | 28 | needles.forEach((n) => { 29 | if (!closestNeedle && cropText.indexOf(n.start) >= 0) { 30 | closestNeedle = n; 31 | closest = cropText.indexOf(n.start); 32 | } else { 33 | const i = cropText.indexOf(n.start); 34 | if (i >= 0 && i < closest) { 35 | closestNeedle = n; 36 | closest = i; 37 | } 38 | } 39 | }); 40 | 41 | if (closestNeedle && cropText.indexOf(closestNeedle.start) >= 0) { 42 | content.push({ 43 | text: cropText.substring(0, cropText.indexOf(closestNeedle.start)), 44 | type: "text", 45 | }); 46 | cropText = cropText.substring( 47 | cropText.indexOf(closestNeedle.start) + closestNeedle.start.length 48 | ); 49 | 50 | content.push({ 51 | text: cropText.substring(0, cropText.indexOf(closestNeedle.end)), 52 | type: closestNeedle.type, 53 | }); 54 | cropText = cropText.substring( 55 | cropText.indexOf(closestNeedle.end) + closestNeedle.end.length 56 | ); 57 | } else { 58 | content.push({ 59 | text: cropText, 60 | type: "text", 61 | }); 62 | cropText = ""; 63 | } 64 | } 65 | return content; 66 | }; 67 | -------------------------------------------------------------------------------- /src/helpers/unique.ts: -------------------------------------------------------------------------------- 1 | // @flow 2 | import { 3 | Format, 4 | Pilot, 5 | Ship, 6 | Size, 7 | SlotKey, 8 | Squadron, 9 | Upgrade, 10 | } from '../types'; 11 | import { slotKeys } from './enums'; 12 | 13 | export const limitedWarning = ( 14 | xws: string, 15 | limited: number, 16 | squadronXWS: string[], 17 | willSelectNew: boolean 18 | ): boolean => { 19 | if (!limited) { 20 | return false; 21 | } 22 | const count = squadronXWS.filter((x) => x === xws.split('-')[0]).length; 23 | // console.log({ count, squadronXWS, xws }); 24 | return willSelectNew ? count >= limited : count > limited; 25 | }; 26 | 27 | export const upgradeFormatWarning = (upgrade: Upgrade, format: Format) => { 28 | switch (format) { 29 | case 'Standard': 30 | return !upgrade.standard; 31 | case 'Epic': 32 | return !upgrade.epic; 33 | case 'Extended': { 34 | const s = upgrade.sides[0].slots; 35 | return ( 36 | s.includes('Cargo') || 37 | s.includes('Command') || 38 | s.includes('Hardpoint') || 39 | s.includes('Team') 40 | ); 41 | } 42 | } 43 | }; 44 | 45 | export const shipFormatWarning = ( 46 | ship: Ship, 47 | format: Format, 48 | validateUpgrades: boolean = true 49 | ) => { 50 | const checkUpgrades = () => { 51 | if (!validateUpgrades) { 52 | return false; 53 | } 54 | let warning = false; 55 | Object.keys(ship.upgrades || {}).forEach((key) => { 56 | const upgrades = ship.upgrades && ship.upgrades[key as SlotKey]; 57 | if (upgrades) { 58 | upgrades.forEach((u) => { 59 | if (upgradeFormatWarning(u, format)) { 60 | warning = true; 61 | } 62 | }); 63 | } 64 | }); 65 | return warning; 66 | }; 67 | 68 | switch (format) { 69 | case 'Standard': { 70 | if (!ship.pilot.standard) { 71 | return true; 72 | } 73 | return checkUpgrades(); 74 | } 75 | 76 | case 'Epic': { 77 | if (!ship.pilot.epic) { 78 | return true; 79 | } 80 | return checkUpgrades(); 81 | } 82 | 83 | case 'Extended': { 84 | if (ship.size === 'Huge') { 85 | return true; 86 | } 87 | 88 | return checkUpgrades(); 89 | } 90 | } 91 | }; 92 | 93 | export const pilotFormatWarning = ( 94 | pilot?: Pilot, 95 | size?: Size, 96 | format?: Format 97 | ) => { 98 | switch (format) { 99 | case 'Standard': { 100 | if (!pilot?.standard) { 101 | return true; 102 | } 103 | break; 104 | } 105 | 106 | case 'Epic': { 107 | if (!pilot?.epic) { 108 | return true; 109 | } 110 | break; 111 | } 112 | 113 | case 'Extended': { 114 | if (size === 'Huge') { 115 | return true; 116 | } 117 | } 118 | } 119 | return false; 120 | }; 121 | 122 | export const squadronFormatWarning = (squadron: Squadron) => { 123 | let warning = false; 124 | squadron.ships.forEach((s) => { 125 | if (shipFormatWarning(s, squadron.format)) { 126 | warning = true; 127 | } 128 | }); 129 | return warning; 130 | }; 131 | 132 | export const usedSquadronXWS = (squadron?: Squadron) => { 133 | let list: string[] = []; 134 | squadron?.ships?.forEach((p) => { 135 | list = [...list, ...usedShipXWS(p)]; 136 | }); 137 | return list; 138 | }; 139 | 140 | export const usedShipXWS = (ship?: Ship): string[] => { 141 | const list = []; 142 | if (ship) { 143 | list.push(ship.pilot.xws.split('-')[0]); 144 | 145 | slotKeys.forEach((key) => { 146 | const upgrades = ship.upgrades && ship.upgrades[key]; 147 | if (upgrades) { 148 | upgrades 149 | .filter((u) => u) 150 | .forEach((u) => list.push(u.xws.split('-')[0])); 151 | } 152 | }); 153 | } 154 | 155 | return list; 156 | }; 157 | -------------------------------------------------------------------------------- /src/helpers/versioning.ts: -------------------------------------------------------------------------------- 1 | export const bumpMajor = (ver: string) => { 2 | const parts = ver.split('.'); 3 | parts[0] = `${parseInt(parts[0]) + 1}`; 4 | return parts.join('.'); 5 | }; 6 | 7 | export const bumpMinor = (ver: string) => { 8 | const parts = ver.split('.'); 9 | parts[1] = `${parseInt(parts[1]) + 1}`; 10 | return parts.join('.'); 11 | }; 12 | 13 | export const bumpPatch = (ver: string) => { 14 | const parts = ver.split('.'); 15 | parts[2] = `${parseInt(parts[2]) + 1}`; 16 | return parts.join('.'); 17 | }; 18 | 19 | export const compareVersions = (a: string, b: string) => { 20 | const aParts = a.split('.').map(x => parseInt(x)); 21 | const bParts = b.split('.').map(x => parseInt(x)); 22 | 23 | if (aParts[0] > bParts[0]) { 24 | return -1; 25 | } 26 | if (aParts[0] < bParts[0]) { 27 | return 1; 28 | } 29 | if (aParts[1] > bParts[1]) { 30 | return -1; 31 | } 32 | if (aParts[1] < bParts[1]) { 33 | return 1; 34 | } 35 | if (aParts[2] > bParts[2]) { 36 | return -1; 37 | } 38 | if (aParts[2] < bParts[2]) { 39 | return 1; 40 | } 41 | return 0; 42 | }; 43 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as Assets from './assets'; 2 | import * as Colors from './assets/colors'; 3 | import * as Helpers from './helpers'; 4 | 5 | export const assets = Assets; 6 | export const colors = Colors; 7 | export const helpers = Helpers; 8 | 9 | export default { 10 | assets: Assets, 11 | colors: Colors, 12 | helpers: Helpers, 13 | }; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "alwaysStrict": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "isolatedModules": true, 9 | "jsx": "preserve", 10 | "lib": ["dom", "es2017"], 11 | "module": "commonjs", 12 | "moduleResolution": "node", 13 | "noEmit": false, 14 | "noFallthroughCasesInSwitch": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "outDir": "./dist", 18 | "resolveJsonModule": true, 19 | "skipLibCheck": true, 20 | "strict": true, 21 | "target": "es5", 22 | }, 23 | "exclude": ["dist"], 24 | "include": ["src/**/*.ts"] 25 | } 26 | --------------------------------------------------------------------------------