Files
dwroller/scripts/parse-weapons.js
2025-08-15 16:23:34 +02:00

129 lines
7.1 KiB
JavaScript

const weaponsData = `
Angelus Bolter Basic - Bolt Range 50m; S/3/-; 1d10+9 X; Pen 6; Clip 36; Reload 2 Full; Tearing 25 Respected Deathwatch First Founding 97
Argrax Clawed Hooves Natural - Primitive 1d10 I; Pen 0; 0 Any Deathwatch The Emperor Protects 46
Armour of the Remorseless Crusader (Forearm Sword) One-Handed Melee - Primitive 1d10+8 R; Pen 6; +10 to hit; Sanctified 70 Hero Deathwatch Deathwatch Core Rulebook 167
Artificer Omnissian Axe One-Handed Melee - Power 1d10+9 E; Pen 7; Power Field, Unbalanced 25 Distinguished Deathwatch First Founding 99
Astartes Anti-Plant Grenade Thrown - Grenade 3d10 E; Pen 0; Blast (3) 18 Any Deathwatch Living Errata v1.1 136
Astartes Armoursbane Missile Launcher Heavy - Launch Range 200m; S/-/-; 0d0 S; Pen 0; Clip 1; Reload 2 Full; Two handed; 15 Any Deathwatch Living Errata v1.1 137
Astartes Assault Cannon Mounted - Solid Projectile Range 150m; -/-/10; 2d10+12 I; Pen 6; Clip 200; Reload 3 Full; Tearing, Devastating (1) 30 Famed Deathwatch Living Errata v1.1 149
Astartes Assault Shotgun Basic - Solid Projectile Range 30m; S/3/5; 1d10+10 I; Pen 4; Clip 20; Reload 1 Full; Two handed; Reliable, Scatter 7 Any Deathwatch Living Errata v1.1 136
Astartes Blind Grenade Thrown - Grenade 0d0 S; Pen 0; Smoke (10) 10 Any Deathwatch Living Errata v1.1 150
Astartes Bolt Pistol Pistol - Bolt Range 30m; S/2/-; 1d10+9 X; Pen 4; Clip 14; Reload 1 Full; Tearing 5 Any Deathwatch Living Errata v1.1 146
Astartes Bolter-Godwyn Basic - Bolt Range 100m; S/3/-; 1d10+9 X; Pen 4; Clip 28; Reload 1 Full; Two handed; Tearing 5 Any Deathwatch Living Errata v1.1 146
Astartes Boltgun-Stalker Basic - Bolt Range 200m; S/-/-; 1d10+9 X; Pen 4; Clip 24; Reload 1 Full; Two handed; Accurate, Tearing 15 Respected Deathwatch Living Errata v1.1 146
Astartes Chainfist One-Handed Melee - Power 2d10+"2*SB" E; Pen 10; Power Field, Tearing, Unwieldy 40 Famed Deathwatch Living Errata v1.1 154
Astartes Chainsword One-Handed Melee - Chain 1d10+3 R; Pen 3; Balanced, Tearing 5 Any Deathwatch Living Errata v1.1 153
Astartes Combat Knife One-Handed Melee - Primitive 1d10 R; Pen 2; 3 Any Deathwatch Living Errata v1.1 155
Astartes Combat Shield One-Handed Melee - Primitive 1d5+1 I; Pen 0; Balanced 20 Distinguished Deathwatch Living Errata v1.1 166
Astartes Combi-Weapon Basic - Bolt Range 100m; S/4/-; 1d10+9 X; Pen 4; Clip 28; Reload 1 Full; Two handed; Tearing 15 Respected Deathwatch Living Errata v1.1 146
Astartes Conversion Beamer Heavy - Exotic Range 100m; S/-/-; 0d0 E; Pen 0; Clip 4; Reload 2 Full; Two handed; 40 Hero Deathwatch Living Errata v1.1 152
Astartes Cyclone Missile Launcher Mounted - Launch Range 300m; S/2/-; 0d0 S; Pen 0; Clip 12; Reload 3 Full; 25 Famed Deathwatch Living Errata v1.1 152
Astartes Digital Flamer Pistol - Exotic Range 4m; S/-/-; 1d10+9 E; Pen 4; Clip 1; Reload 1d5 Hours; Flame, Spray 35 Famed Deathwatch Living Errata v1.1 153
Astartes Chainfist One-Handed Melee - Power 2d10+"2*SB" E; Pen 10; Power Field, Tearing, Unwieldy 40 Famed Deathwatch Living Errata v1.1 154
Astartes Chainfist One-Handed Melee - Power 2d10+"2*SB" E; Pen 10; Power Field, Tearing 40 Famed Deathwatch Deathwatch Core Rulebook 154
Astartes Chainsword One-Handed Melee - Chain 1d10+3 R; Pen 4; Balanced, Tearing 5 Any Deathwatch Deathwatch Core Rulebook 153
Astartes Chainsword One-Handed Melee - Chain 1d10+3 R; Pen 3; Balanced, Tearing 5 Any Deathwatch Living Errata v1.1 153
Astartes Combat Knife One-Handed Melee - Primitive 1d10 R; Pen 2; 3 Any Deathwatch Living Errata v1.1 155
Astartes Combat Knife One-Handed Melee - Primitive 1d10+2 R; Pen 2; 3 Any Deathwatch Deathwatch Core Rulebook 155
Astartes Combat Shield One-Handed Melee - Primitive 1d5+1 I; Pen 0; Balanced 20 Distinguished Deathwatch Living Errata v1.1 166
Astartes Combat Shield One-Handed Melee - Primitive 1d5+1 I; Pen 0; Balanced 20 Distinguished Deathwatch Deathwatch Core Rulebook 166
Astartes Combi-Weapon Basic - Bolt Range 100m; S/2/4; 2d10+5 X; Pen 5; Clip 28; Reload 1 Full; Two handed; Tearing 15 Respected Deathwatch Deathwatch Core Rulebook 146
`;
// Parse weapon data into structured objects
const parseWeapons = (data) => {
const lines = data.split('\n').filter(line => line.trim());
return lines.map(line => {
const cols = line.split('\t').map(col => col.trim());
if (cols.length >= 8) {
return {
name: cols[0],
class: cols[1],
damage: cols[2],
cost: parseInt(cols[3]) || 0,
availability: cols[4],
gameSetting: cols[5],
book: cols[6],
pageNo: cols[7]
};
}
return null;
}).filter(w => w !== null);
};
// Map availability levels to renown levels
const availabilityToRenown = {
'Any': 'None',
'Common': 'None',
'Scarce': 'None',
'Rare': 'Respected',
'Very Rare': 'Distinguished',
'Extremely Rare': 'Hero',
'Near Unique': 'Hero',
'Unique': 'Legend',
'Distinguished': 'Distinguished',
'Famed': 'Hero',
'Respected': 'Respected',
'Hero': 'Hero'
};
// Map weapon classes to shop categories
const classToCategory = (itemClass) => {
const lowerClass = itemClass.toLowerCase();
if (lowerClass.includes('melee')) return 'Melee Weapon';
if (lowerClass.includes('pistol')) return 'Ranged Weapon';
if (lowerClass.includes('basic') ||
lowerClass.includes('heavy') ||
lowerClass.includes('mounted')) return 'Ranged Weapon';
if (lowerClass.includes('thrown')) return 'Grenade';
return 'Other';
};
// Process weapons into shop format
const processWeapons = () => {
const weapons = parseWeapons(weaponsData);
// Use a Map to deduplicate items (keeping only the Living Errata version when available)
const uniqueWeapons = new Map();
weapons.forEach(weapon => {
const key = weapon.name;
const existing = uniqueWeapons.get(key);
// Prefer Living Errata over Core Rulebook
if (!existing || weapon.book.includes('Living Errata')) {
uniqueWeapons.set(key, {
name: weapon.name,
req: parseInt(weapon.cost),
renown: availabilityToRenown[weapon.availability] || 'Distinguished',
category: classToCategory(weapon.class),
stats: {
damage: weapon.damage,
class: weapon.class,
source: `${weapon.book} p${weapon.pageNo}`
}
});
}
});
return Array.from(uniqueWeapons.values());
};
// Process weapons and organize by category
const weapons = processWeapons();
const categorizedWeapons = {
rangedWeapons: weapons.filter(item => item.category === 'Ranged Weapon'),
meleeWeapons: weapons.filter(item => item.category === 'Melee Weapon'),
grenades: weapons.filter(item => item.category === 'Grenade'),
other: weapons.filter(item => item.category === 'Other')
};
if (require.main === module) {
const fs = require('fs');
const path = require('path');
const output = path.resolve('public/deathwatch-weapons.json');
fs.writeFileSync(output, JSON.stringify(categorizedWeapons, null, 2), 'utf8');
console.log('Wrote weapon data to:', output);
}
module.exports = { categorizedWeapons, processWeapons };